[Pkg-voip-commits] r1918 - in zaptel/trunk: . cwain debian debian/patches qozap zaphfc ztgsm

Tzafrir Cohen tzafrir-guest at costa.debian.org
Mon Jun 19 20:27:35 UTC 2006


Author: tzafrir-guest
Date: 2006-06-19 20:27:22 +0000 (Mon, 19 Jun 2006)
New Revision: 1918

Added:
   zaptel/trunk/cwain/
   zaptel/trunk/cwain/LICENSE
   zaptel/trunk/cwain/Makefile
   zaptel/trunk/cwain/TODO
   zaptel/trunk/cwain/cwain.c
   zaptel/trunk/cwain/cwain.h
   zaptel/trunk/cwain/zapata.conf
   zaptel/trunk/cwain/zapata.conf.doubleE1
   zaptel/trunk/cwain/zaptel.conf
   zaptel/trunk/cwain/zaptel.conf.doubleE1
   zaptel/trunk/qozap/
   zaptel/trunk/qozap/LICENSE
   zaptel/trunk/qozap/Makefile
   zaptel/trunk/qozap/TODO
   zaptel/trunk/qozap/qozap.c
   zaptel/trunk/qozap/qozap.h
   zaptel/trunk/qozap/zapata.conf
   zaptel/trunk/qozap/zapata.conf.octoBRI
   zaptel/trunk/qozap/zaptel.conf
   zaptel/trunk/qozap/zaptel.conf.octoBRI
   zaptel/trunk/zaphfc/
   zaptel/trunk/zaphfc/LICENSE
   zaptel/trunk/zaphfc/Makefile
   zaptel/trunk/zaphfc/zapata.conf
   zaptel/trunk/zaphfc/zaphfc.c
   zaptel/trunk/zaphfc/zaphfc.h
   zaptel/trunk/zaphfc/zaptel.conf
   zaptel/trunk/ztgsm/
   zaptel/trunk/ztgsm/LICENSE
   zaptel/trunk/ztgsm/Makefile
   zaptel/trunk/ztgsm/TODO
   zaptel/trunk/ztgsm/zapata.conf.duoGSM
   zaptel/trunk/ztgsm/zapata.conf.quadGSM
   zaptel/trunk/ztgsm/zapata.conf.unoGSM
   zaptel/trunk/ztgsm/zaptel.conf.duoGSM
   zaptel/trunk/ztgsm/zaptel.conf.quadGSM
   zaptel/trunk/ztgsm/zaptel.conf.unoGSM
   zaptel/trunk/ztgsm/ztgsm.c
   zaptel/trunk/ztgsm/ztgsm.h
Modified:
   zaptel/trunk/debian/changelog
   zaptel/trunk/debian/patches/bristuff.dpatch
   zaptel/trunk/debian/rules
   zaptel/trunk/debian/zaptel-source.dirs
Log:
* Separating ZapBRI modules to directories, rather than patches
* Example configs moved from zaptel-source to zaptel
* Removing some unneeded dirs from zaptel-source


Added: zaptel/trunk/cwain/LICENSE
===================================================================
--- zaptel/trunk/cwain/LICENSE	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/LICENSE	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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.

Added: zaptel/trunk/cwain/Makefile
===================================================================
--- zaptel/trunk/cwain/Makefile	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/Makefile	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,90 @@
+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) -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 -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)
+
+OBJS=cwain.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=cwain
+
+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)
+
+cwain.o: cwain.c cwain.h 
+	$(CC) -c cwain.c $(KFLAGS)
+
+clean:	
+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
+	
+testlinux24: all
+	modprobe zaptel
+	insmod ./cwain.o
+	ztcfg -v
+	cat /proc/interrupts
+	sleep 1
+	cat /proc/interrupts
+	rmmod cwain zaptel
+
+testlinux26: all
+	modprobe zaptel
+	insmod ./cwain.ko
+	ztcfg -v
+	cat /proc/interrupts
+	sleep 5
+	cat /proc/interrupts
+	rmmod cwain zaptel
+
+reload:	unload load
+load:	load$(BUILDVER)
+
+test:	test$(BUILDVER)
+
+
+loadlinux24: linux24
+	modprobe zaptel
+	insmod ./cwain.o
+	ztcfg -v
+
+loadlinux26: linux26
+	sync
+	modprobe zaptel
+	insmod ./cwain.ko debug=1
+	ztcfg -v
+
+install:	install$(BUILDVER)
+
+installlinux26:
+	install -D -m 644 cwain.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/cwain.ko
+
+installlinux24:
+	install -D -m 644 cwain.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/cwain.o
+
+unload: 
+	rmmod cwain zaptel

Added: zaptel/trunk/cwain/TODO
===================================================================
--- zaptel/trunk/cwain/TODO	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/TODO	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1 @@
+

Added: zaptel/trunk/cwain/cwain.c
===================================================================
--- zaptel/trunk/cwain/cwain.c	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/cwain.c	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,1629 @@
+/*
+ * cwain.c - Zaptel driver for the Junghanns.NET E1 card
+ *
+ * c.w.a.i.n. == card without an interesting name
+ *
+ * single/double E1 board
+ *
+ * Copyright (C) 2004, 2005 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 "cwain.h"
+
+#if CONFIG_PCI
+
+static int ports=-1; /* autodetect */
+static int debug=0;
+static struct zt_cwain *cwain_span_list = NULL;
+static int cwain_span_count = 0;
+static struct zt_cwain_card *cwain_card_list = NULL;
+static int cwain_card_count = 0;
+static struct pci_dev *multi_cwain = NULL;
+static spinlock_t cwain_span_registerlock = SPIN_LOCK_UNLOCKED;
+static spinlock_t cwain_card_registerlock = SPIN_LOCK_UNLOCKED;
+
+static int ztcwain_shutdown(struct zt_span *span);
+
+int cwain_waitbusy(struct zt_cwain *cwaintmp) {
+    int x=1000;
+    while (x-- && (cwain_inb(cwaintmp,cwain_R_STATUS) & 1));
+    if (x < 0) {
+	printk(KERN_CRIT "cwain: really busy waiting!\n");
+	return -1;
+    } else {
+	if ((x < 990) && (cwaintmp->ticks > 500)) {
+	    printk(KERN_CRIT "cwain: waited %d\n", 1000 - x);
+	}
+	return 0;
+    }
+}
+
+void cwain_unregister_zap_span(struct zt_cwain *cwainspan) {
+    if (!cwainspan) {
+	printk(KERN_INFO "cwain: shutting down NULL span!\n");
+	return;
+    }
+    if(cwainspan->span.flags & ZT_FLAG_RUNNING) {
+        ztcwain_shutdown(&cwainspan->span);
+        if (debug)
+            printk(KERN_INFO "cwain: shutdown span %d.\n",cwainspan->cardno);
+    }
+    if(cwainspan->span.flags & ZT_FLAG_REGISTERED) {
+        zt_unregister(&cwainspan->span);
+        if (debug)
+    	printk(KERN_INFO "cwain: unregistered span %d.\n",cwainspan->cardno);
+    }
+}
+
+void cwain_shutdown_span(struct zt_cwain *cwainspan) {
+    
+    if (!cwainspan) {
+	printk(KERN_INFO "cwain: shutting down NULL span!\n");
+	return;
+    }
+
+    if (cwainspan->pci_io == NULL) {
+	return;
+    }
+
+    if (debug)
+	printk(KERN_INFO "cwain: shutting down span %d (cardID %d) at %p.\n",cwainspan->cardno,cwainspan->cardID,cwainspan->pci_io);
+
+    // turn off irqs
+
+    // softreset
+    cwain_outb(cwainspan,cwain_R_CIRM,0x8);
+    cwain_outb(cwainspan,cwain_R_CIRM,0x0); 
+    cwain_waitbusy(cwainspan);
+
+    cwain_outb(cwainspan,cwain_R_IRQMSK_MISC, 0); 
+    cwain_outb(cwainspan,cwain_R_IRQ_CTRL, 0); 
+
+    pci_write_config_word(cwainspan->pcidev, PCI_COMMAND, 0);	// disable memio
+
+    if (cwainspan->pcidev != NULL) {
+        pci_disable_device(cwainspan->pcidev);
+	cwainspan->pcidev = NULL;
+    }
+
+//    iounmap((void *) cwainspan->pci_io);
+//    cwainspan->pci_io = NULL;
+}
+
+void cwain_shutdown_card(struct zt_cwain_card *cwaintmp) {
+    unsigned long flags = 0;
+    int i = 0;
+    
+    if (!cwaintmp) {
+	printk(KERN_INFO "cwain: shutting down NULL card!\n");
+	return;
+    }
+
+    for (i=0;i<cwaintmp->spans;i++) {
+	cwain_unregister_zap_span(cwaintmp->span[i]);
+    }
+
+    spin_lock_irqsave(&cwaintmp->lock,flags);
+
+    // turn off irqs
+    cwain_outb(cwaintmp->span[0],cwain_R_IRQ_CTRL, 0); 
+    cwain_outb(cwaintmp->span[0],cwain_R_IRQMSK_MISC, 0); 
+
+    for (i=0;i<cwaintmp->spans;i++) {
+	cwain_shutdown_span(cwaintmp->span[i]);
+    }
+    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);
+}
+
+void cwain_doLEDs(struct zt_cwain *cwaintmp) {
+    /*
+     O1 O3 (red)
+     O2 O4 (green)
+    */
+    if (!(cwaintmp->span.flags & ZT_FLAG_RUNNING)) {
+	return;
+    }
+    if ((cwaintmp->type == 0xb553) || (cwaintmp->type == 0xb554)) {
+	/* sync status */
+	if (((cwaintmp->sync_sta & 0x07) == 0x07) && cwaintmp->sync) {
+	    cwaintmp->leds[0] = 1;    
+	    cwaintmp->leds[1] = 0;    
+	} else {
+	    cwaintmp->leds[0] = 0;    
+	    cwaintmp->leds[1] = 1;    
+	}
+	/* multiframe alignment */
+	if ((cwaintmp->sync_sta & 0x20) == 0x20) {
+    	    cwaintmp->leds[2] = 1;    
+	    cwaintmp->leds[3] = 0;    
+	} else {
+	    if ((cwaintmp->span.lineconfig & ZT_CONFIG_CRC4) && cwaintmp->sync) {
+		/* CRC4 requested */
+		cwaintmp->leds[2] = 0;    
+		cwaintmp->leds[3] = 1;    
+	    } else {
+		/* no CRC4, disable 3 and 4 */
+		cwaintmp->leds[2] = 1;    
+		cwaintmp->leds[3] = 1;    
+	    }
+	}
+	cwain_outb(cwaintmp,cwain_R_GPIO_OUT1,(cwaintmp->leds[0] | (cwaintmp->leds[1] << 1) | (cwaintmp->leds[2] << 2) | (cwaintmp->leds[3] << 3)));
+    }
+}
+
+void cwain_reset_span(struct zt_cwain *cwaintmp) {
+    int i = 0;
+    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);
+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
+    cwain_waitbusy(cwaintmp);
+
+    /* PCM reset */
+    cwain_outb(cwaintmp,cwain_R_CIRM,0x20);
+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
+    cwain_waitbusy(cwaintmp);
+
+    for (i=0; i<128; i++) {
+	cwain_outb(cwaintmp,cwain_R_SLOT, i);
+	cwain_outb(cwaintmp,cwain_A_SL_CFG, 0x0);
+    }
+    
+    /* E1 reset */
+    cwain_outb(cwaintmp,cwain_R_CIRM,0x40);
+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
+    cwain_waitbusy(cwaintmp);
+
+    /* 128 byte B chans, 4096 byte D chans */
+    cwain_outb(cwaintmp,cwain_R_FIFO_MD,0x36);
+    cwain_outb(cwaintmp,cwain_R_BRG_PCM_CFG,0x0); 
+    cwain_outb(cwaintmp,cwain_R_CTRL,0x0); 
+
+    /* no blinky blink */
+    cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10);
+    cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
+    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;    
+    cwaintmp->leds[1] = 1;    
+    cwaintmp->leds[2] = 1;    
+    cwaintmp->leds[3] = 1;    
+    
+    cwaintmp->ticks = 0;
+    cwaintmp->clicks = 0;
+}
+
+struct zt_cwain_card *cwain_get_card(unsigned int pcibus) {
+    struct zt_cwain_card *cwaintmp = cwain_card_list;
+    spin_lock(&cwain_card_registerlock);
+    while (cwaintmp) {
+	if (cwaintmp->pcibus == pcibus) {
+	    break;
+	}
+	cwaintmp = cwaintmp->next;
+    }
+    spin_unlock(&cwain_card_registerlock);
+    return cwaintmp;
+}
+
+
+void cwain_register_card(struct zt_cwain_card *cwaincard) {
+    spin_lock(&cwain_card_registerlock);
+    if (cwaincard != NULL) {
+	cwaincard->prev = NULL;
+	cwaincard->next = cwain_card_list;
+	if (cwain_card_list) {
+	    cwain_card_list->prev = cwaincard;
+	}
+	cwain_card_list = cwaincard;
+	cwain_card_count++;
+    } else {
+	printk(KERN_INFO "cwain: trying to register NULL card.\n");
+    }
+    spin_unlock(&cwain_card_registerlock);
+}
+
+int cwain_register_span(struct zt_cwain *cwainspan) {
+    struct zt_cwain_card *cwaintmp;
+    spin_lock(&cwain_span_registerlock);
+    if (cwainspan != NULL) {
+	cwainspan->prev = NULL;
+	cwainspan->next = cwain_span_list;
+	if (cwain_span_list) {
+	    cwain_span_list->prev = cwainspan;
+	}
+	cwain_span_list = cwainspan;
+	cwainspan->cardno = ++cwain_span_count;
+    } else {
+	printk(KERN_INFO "cwain: trying to register NULL span.\n");
+    }
+    spin_unlock(&cwain_span_registerlock);
+
+    if (cwainspan->type == 0xb553) {
+	cwaintmp = kmalloc(sizeof(struct zt_cwain_card),GFP_KERNEL);
+	if (!cwaintmp) {
+	    printk(KERN_WARNING "cwain: unable to kmalloc!\n");
+	    return -1;
+	}
+	memset(cwaintmp, 0x0, sizeof(struct zt_cwain_card));
+	
+	spin_lock_init(&cwaintmp->lock);
+	cwaintmp->pcibus = cwainspan->pcibus;
+	cwaintmp->span[0] = cwainspan;
+	cwaintmp->syncs[0] = -1;
+	cwaintmp->spans = 1;
+	cwaintmp->cardID = cwainspan->cardID;
+	cwain_register_card(cwaintmp);
+	printk(KERN_INFO
+	        "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);
+	if (!cwaintmp) {
+	    cwaintmp = kmalloc(sizeof(struct zt_cwain_card),GFP_KERNEL);
+	    if (!cwaintmp) {
+		printk(KERN_WARNING "cwain: unable to kmalloc!\n");
+	        return -1;
+	    }
+	    memset(cwaintmp, 0x0, sizeof(struct zt_cwain_card));
+	
+	    spin_lock_init(&cwaintmp->lock);
+	    cwaintmp->pcibus = cwainspan->pcibus;
+	    cwaintmp->spans = cwainspan->type - 46419;
+	    cwaintmp->span[0] = cwainspan;
+	    cwaintmp->cardID = cwainspan->cardID;
+	    cwaintmp->syncs[0] = -1;
+	    cwain_register_card(cwaintmp);
+	} else {
+	    cwaintmp->spans = cwainspan->type - 46418;
+	    if (cwainspan->cardID < cwaintmp->cardID) {
+		cwaintmp->cardID = cwainspan->cardID;
+		cwaintmp->span[1] = cwaintmp->span[0];
+		cwaintmp->syncs[1] = cwaintmp->syncs[0];
+	        cwaintmp->span[0] = cwainspan;
+	    } else {
+	        cwaintmp->span[1] = cwainspan;
+		cwaintmp->syncs[1] = -1;
+	    }
+	    printk(KERN_INFO
+	        "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);
+	}
+    }
+    return 0;
+}
+
+static int cwain_dfifo_tx(struct zt_cwain *cwaintmp) {
+    int chan = 15;
+    int x=0;
+    char fifo = 0;
+
+    fifo = 0x1F;
+
+    if (cwaintmp->chans[chan].bytes2transmit < 1) {
+	return 0;
+    } else {
+	/* select fifo */
+	cwain_outb(cwaintmp,cwain_R_FIFO,fifo << 1);    
+	cwain_waitbusy(cwaintmp);
+    
+	if (debug)
+	    printk(KERN_INFO "cwain: card %d TX [ ", cwaintmp->cardno);
+	/* copy frame to fifo */
+    	for (x=0;x<cwaintmp->chans[chan].bytes2transmit;x++) {
+	    if (debug)
+	        printk("%#x ",cwaintmp->dtxbuf[x]);
+    	    cwain_outb(cwaintmp,cwain_A_FIFO_DATA0,cwaintmp->dtxbuf[x]);
+	}
+	if (debug)
+	    printk("]\n");
+	if (debug)
+    	    printk(KERN_INFO "ztx %d bytes\n",cwaintmp->chans[chan].bytes2transmit);
+
+	if (cwaintmp->chans[chan].eoftx == 1) {
+	    /* transmit HDLC frame */
+    	    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x1);    
+    	    cwain_waitbusy(cwaintmp);
+	}
+    }
+    return 0;
+}
+
+static int cwain_fifo_tx(struct zt_cwain *cwaintmp, char fifo) {
+    int chan,f;
+    if (fifo >= 15) {
+	chan = fifo;
+    } else {
+	chan = fifo;
+    }
+    /* select fifo */
+    cwain_outb(cwaintmp,cwain_R_FIFO,0x80 | (fifo << 1));    
+    cwain_waitbusy(cwaintmp);
+    
+    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;
+}
+
+static int cwain_dfifo_rx(struct zt_cwain *cwaintmp) {
+    int chan = 15;
+    unsigned char f1=1,f2=1,data,stat;
+    unsigned char of1=0,of2=0;
+    int len,i;
+    unsigned short z1=1,z2=1;
+    unsigned short oz1=0,oz2=0;
+    char fifo = 0;
+
+    fifo = 0x1F;
+    
+    /* select fifo */
+    cwain_outb(cwaintmp,cwain_R_FIFO,(fifo << 1) | 1);    
+    cwain_waitbusy(cwaintmp);
+    
+    while ((oz1 != z1) && (oz2 != z2)) {
+        oz1 = z1;
+        oz2 = z2;
+    	z1 = cwain_inw(cwaintmp,cwain_A_Z1) & 0xfff;
+	z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0xfff;
+    }
+    
+    len = z1-(z2 & 0xfff);
+    if (len < 0) {
+        len += cwain_DFIFO_SIZE;
+    }
+
+    while ((of1 != f1) && (of2 != f2)) {
+        of1 = f1;
+        of2 = f2;
+        f1 = cwain_inb(cwaintmp,cwain_A_F1) & 0xf;
+        f2 = cwain_inb(cwaintmp,cwain_A_F2) & 0xf;
+    }
+
+    if (len > cwain_DFIFO_SIZE) {
+	printk(KERN_INFO "\ncwain: buffer overflow in D channel RX!\n");
+	cwaintmp->chans[chan].bytes2receive = 0;
+	cwaintmp->chans[chan].eofrx = 0;
+    } else {
+	if (debug) printk(KERN_INFO "cwain: card %d RX [ ", cwaintmp->cardno);
+	for (i=0; i<len; i++) {
+    	    data = cwain_inb(cwaintmp,cwain_A_FIFO_DATA0);
+	    cwaintmp->drxbuf[i] = data;
+	    if (debug) printk("%#x ",data);
+	}
+	if (debug) printk("] %d bytes\n", i);
+	cwaintmp->chans[chan].bytes2receive = i;
+	cwaintmp->chans[chan].eofrx = 1;
+    }
+
+    stat = cwain_inb(cwaintmp,cwain_A_FIFO_DATA0);
+    if (stat != 0x0) {
+	// bad CRC, skip it
+	if (cwaintmp->sync) {
+	    printk(KERN_INFO "cwain: BAD CRC for hdlc frame on card %d (cardID %d) stat %#x\n",cwaintmp->cardno, cwaintmp->cardID, stat);
+	}
+	cwaintmp->chans[chan].bytes2receive = 0;
+	cwaintmp->chans[chan].eofrx = 0;
+//	    zt_qevent_nolock(&cwaintmp->spans[stport].chans[chan], ZT_EVENT_BADFCS);
+    }
+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x1);    
+    cwain_waitbusy(cwaintmp);
+
+    /* frame received */
+    cwaintmp->drx--;
+    return 0;
+}
+
+
+static int cwain_fifo_rx(struct zt_cwain *cwaintmp, char fifo) {
+    int chan;
+    unsigned int data;
+    int len,i,f,flen = 0;
+    unsigned short z1=1,z2=1;
+    unsigned short oz1=0,oz2=0;
+    int mumbojumbo=0;
+    int x = 1000;
+
+    chan = fifo;
+
+    // select rx fifo
+    
+	// no hdlc, transparent data
+	cwain_outb(cwaintmp,cwain_R_FIFO,0x80 | (fifo << 1) | 1);    
+        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) & 0x7f;
+    	    z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0x7f;
+	}
+	if (x < 500) {
+	    printk(KERN_CRIT "cwain: prevented endless loop\n");
+	}
+    
+	if (mumbojumbo > 0) {
+	    for (i=0;i<(mumbojumbo/4);i++) {
+    		data = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
+	    }
+	    cwaintmp->clicks++;
+	}
+	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 {
+	    for (f=0;f<(cwain_FRAME_SIZE / 4);f++) {
+		*((unsigned int *) &cwaintmp->frxbuf[chan][f*4]) = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
+	    }
+	}
+
+
+	/* 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);    
+    return 0;
+}
+
+void cwain_set_master(struct zt_cwain_card *cwaintmp, int span) {
+    int i=0;
+
+    if (cwaintmp->syncsrc == span) return;
+    
+    for (i=0; i < cwaintmp->spans; i++) {
+	if (i != span) {
+	    if (cwaintmp->syncs[i] > 0) {
+		/* enable PCM slave mode, PCM32, synced to E1 receive */
+    		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD0, 0x90);
+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD1, 0x0);
+		cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA0);
+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD2, 0x00);
+	    } else {
+		/* enable PCM slave mode, PCM32 */
+    		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD0, 0x90);
+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD1, 0x0);
+		cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA0);
+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD2, 0x00);
+	    }
+	    cwaintmp->master[i] = 0;
+	    cwaintmp->span[i]->span.syncsrc = 0;
+	}
+    }
+
+    if (cwaintmp->syncs[span] > 0) {
+        /* enable PCM master mode, PCM32, synced to E1 receive */
+	if (debug)
+	    printk(KERN_INFO "cwain: cardID %d span %d, PCM master E1 sync\n", cwaintmp->cardID, span);
+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0x91);
+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD1, 0x0);
+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA1);
+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD2, 0x00);
+	cwaintmp->span[span]->span.syncsrc = 1;
+    } else {
+        /* enable PCM master mode, PCM32, free running */
+	if (debug)
+	    printk(KERN_INFO "cwain: cardID %d span %d, PCM master\n", cwaintmp->cardID, span);
+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0x91);
+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD1, 0x0);
+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA1);
+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD2, 0x04);
+	cwaintmp->span[span]->span.syncsrc = 0;
+    }
+    
+    cwaintmp->master[span] = 1;
+    cwaintmp->syncsrc = span;
+}
+
+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->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;
+		}
+	    } else {
+	        bestsync = i;
+	    }
+	}
+    }
+
+    if (cwaintmp->syncsrc >= 0) {
+	if (debug > 3)
+	    printk(KERN_INFO "cwain: bestsync %d cwaintmp->syncsrc %d\n", bestsync, cwaintmp->syncsrc);
+	
+	if (bestsync == cwaintmp->syncsrc) {
+	    if (debug > 3)
+		printk(KERN_INFO "cwain: already on best syncsrc %d\n", bestsync);
+	    return;
+	}
+
+	/* if we have a better syncsrc */
+	if (bestsync < cwaintmp->spans) {
+	    if (debug)
+		printk(KERN_INFO "cwain: found better syncsrc %d\n", bestsync);
+	    cwain_set_master(cwaintmp, bestsync);
+	    return;		    
+	}
+    }
+
+    /* if reelection failed, find internal sync source */
+    if (cwaintmp->syncsrc == -1) {
+	/* no master yet */
+	if (debug > 3)
+	    printk(KERN_INFO "cwain: no clocksource found cardID %d\n", cwaintmp->cardID);
+	for (i=0; i < cwaintmp->spans; i++) {
+	    /* find the first internal source */
+	    if (debug > 3)
+	        printk(KERN_INFO "cwain: cwaintmp->syncs[%d] = %d\n", i, cwaintmp->syncs[i]);
+	    if (cwaintmp->syncs[i] == 0) {
+		if (debug)
+		    printk(KERN_INFO "cwain: using internal clock of span %d\n", i);
+		cwain_set_master(cwaintmp, i);
+		return;
+	    }
+	}
+    }
+
+    /* if we have no internal sync source the only thing we can do is to enable any of the possible sync sources*/
+    if (cwaintmp->syncsrc == -1) {
+	/* find the first possible sync source with framing */
+        for (i=0; i < cwaintmp->spans; i++) {
+	    if (cwaintmp->syncs[i] > 0) {
+		if (debug)
+		    printk(KERN_INFO "cwain: desperately using clock of span %d\n", i);
+		cwain_set_master(cwaintmp, i);
+		break;
+	    }
+	}
+    }
+}
+
+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... */
+        zt_transmit(&cwaintmp->span);
+	/* B chans 1-15 mapped to fifos 0-14 */
+	/* B chans 17-31 mapped to fifos 15-29 */
+	for (fifo=0; fifo < 30; 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);
+	}
+
+        cwaintmp->chans[15].bytes2receive = 0;
+	cwaintmp->chans[15].bytes2transmit = 0;
+	cwaintmp->chans[15].eofrx = 0;
+	cwaintmp->chans[15].eoftx = 0;
+
+	for (fifo=0; fifo < 30; 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 */
+	if ((cwaintmp->drx > 0) && cwaintmp->sync){
+	    if (debug > 2)
+	    	printk(KERN_CRIT "drx = %d\n", cwaintmp->drx);
+	    cwain_dfifo_rx(cwaintmp);
+	}
+	/* oh zaptel! thou shall receive! */
+	zt_receive(&(cwaintmp->span));
+    }
+}
+
+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 res;
+    }
+
+    sync_sta = cwain_inb(cwainspan, cwain_R_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 (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;
+	    }
+	} 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);
+		}
+		sync_ok = 0x07;
+	    } else {
+		sync_ok = 0x00;
+	    }
+	}
+
+	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);
+	}
+
+	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);
+	
+	    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.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;
+	}
+	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);
+    }
+    return res;
+}
+
+int cwain_isr_fifo(struct zt_cwain *cwainspan, unsigned char status) {
+    unsigned char irq_foview,fi;
+
+    if (status & 0x80) {
+	/* fifo irq */
+	irq_foview = cwain_inb(cwainspan,cwain_R_IRQ_OVIEW);
+	if (irq_foview & 0x80) {
+	    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 cardID %d\n", cwainspan->cardID);
+		cwainspan->drx += 1;		
+	    }
+	}
+	return 1;
+    }
+    return 0;
+}
+
+#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 = 0;
+#ifndef RELAXED_LOCKING    
+    unsigned long flags;
+#endif
+    int i = 0;
+    int l1event = 0;
+    
+    if (!cwaintmp || cwaintmp->dead) {
+#ifdef LINUX26
+		return IRQ_NONE;
+#else
+		return;
+#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;
+
+    for (i=0;i<cwaintmp->spans;i++) {
+	if (i == 0) {
+	    status_tmp = status;
+	} else {
+	    status_tmp = cwain_inb(cwaintmp->span[i],cwain_R_STATUS);
+	    status2 = status_tmp;
+	}
+	cwain_isr_fifo(cwaintmp->span[i], status_tmp);
+    }
+
+    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
+		return;
+#endif		
+    }
+
+    // misc irq
+    if (status & 0x40) {
+	irq_misc = cwain_inb(cwaintmp->span[0],cwain_R_IRQ_MISC);
+	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], cwaintmp->ticks);
+	    }
+	    if (cwaintmp->ticks == (cwain_FRAME_SIZE / 8)) {
+		cwaintmp->ticks = 0;
+	    }
+	} 
+	if (irq_misc & 0x1) {
+	    /* state machine */
+	    if (debug > 4)
+		printk(KERN_INFO "cwain: state machine irq\n");
+	    l1event++;
+	}
+	if (irq_misc & 0x10) {
+    	    if (l1event == 0) {
+		/* just in case we missed it */
+		for (i=0;i<cwaintmp->spans;i++) {
+    	    	    l1event += cwain_isr_sync(cwaintmp->span[i]);
+    		}
+	    }
+	}
+    }
+
+    // misc irq
+    if (status2 & 0x40) {
+	if (cwaintmp->spans == 2) {
+	    irq_misc2 = cwain_inb(cwaintmp->span[1],cwain_R_IRQ_MISC);
+	}
+	if (irq_misc2 & 0x1) {
+	    /* state machine 2 */
+	    if (debug > 4)
+		printk(KERN_INFO "cwain: state machine 2 irq\n");
+	    l1event++;
+	}
+    }
+
+    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);
+        }
+    }
+
+#ifdef RELAXED_LOCKING    
+    spin_unlock(&(cwaintmp->lock));
+#else
+    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
+#endif
+#ifdef LINUX26
+	return IRQ_RETVAL(1);
+#endif		
+}
+
+static int ztcwain_open(struct zt_chan *chan) {
+//    printk(KERN_INFO "cwain: channel %d opened.\n",chan->channo);
+#ifndef LINUX26
+    MOD_INC_USE_COUNT;
+#else
+    try_module_get(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int ztcwain_close(struct zt_chan *chan) {
+//    printk(KERN_INFO "cwain: channel %d closed.\n",chan->channo);
+#ifndef LINUX26
+    MOD_DEC_USE_COUNT;
+#else
+    module_put(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int ztcwain_rbsbits(struct zt_chan *chan, int bits) {
+    return 0;
+}
+
+static int ztcwain_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
+        switch(cmd) {
+        default:
+                return -ENOTTY;
+        }
+        return 0;
+}
+
+static int ztcwain_startup(struct zt_span *span) {
+    struct zt_cwain_card *cwaincard = span->pvt;
+    struct zt_cwain *cwaintmp;
+    unsigned long flags;
+    int alreadyrunning;
+    int i=0;
+
+//    printk(KERN_INFO "cwain: startup spanno %d offset %d\n", span->spanno, span->offset);
+
+    if (cwaincard == NULL) {
+	printk(KERN_CRIT "cwain: cwaincard == NULL!\n");
+	return 0;
+    }
+
+    cwaintmp = cwaincard->span[span->offset];
+    if (cwaintmp == NULL) {
+	printk(KERN_CRIT "cwain: cwaintmp == NULL!\n");
+	return 0;
+    }
+
+    
+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+//    printk(KERN_CRIT "already running %d flags %d\n", alreadyrunning, span->flags);
+
+    if (!alreadyrunning) {
+	span->chans[15].flags &= ~ZT_FLAG_HDLC;
+	span->chans[15].flags |= ZT_FLAG_BRIDCHAN; /* yes! */
+    
+	/* setup B channel buffers (8 bytes each) */
+	for (i=0; i<15 ; i++) {
+	    memset(cwaintmp->rxbuf[i],0x0,sizeof(cwaintmp->rxbuf[i]));
+    	    memset(cwaintmp->txbuf[i],0x0,sizeof(cwaintmp->txbuf[i]));
+
+    	    span->chans[i].readchunk = cwaintmp->rxbuf[i];
+	    span->chans[i].writechunk = cwaintmp->txbuf[i];
+	}
+	for (i=16; i<31 ; i++) {
+	    memset(cwaintmp->rxbuf[i-1],0x0,sizeof(cwaintmp->rxbuf[i-1]));
+    	    memset(cwaintmp->txbuf[i-1],0x0,sizeof(cwaintmp->txbuf[i-1]));
+    	    span->chans[i].readchunk = cwaintmp->rxbuf[i-1];
+	    span->chans[i].writechunk = cwaintmp->txbuf[i-1];
+	}
+	/* setup D channel buffer */
+    	memset(cwaintmp->dtxbuf,0x0,sizeof(cwaintmp->dtxbuf));
+	span->chans[15].writechunk = cwaintmp->dtxbuf;
+	cwaintmp->chans[15].maxbytes2transmit = sizeof(cwaintmp->dtxbuf);
+
+	memset(cwaintmp->drxbuf,0x0,sizeof(cwaintmp->drxbuf));
+    	span->chans[15].readchunk = cwaintmp->drxbuf;
+
+	span->flags |= ZT_FLAG_RUNNING;
+    } else {
+	printk(KERN_CRIT "already running\n");
+	return 0;
+    }
+
+    spin_lock_irqsave(&cwaintmp->lock,flags);
+    // irqs off
+    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
+
+    /* setup D-FIFO TX */
+    cwain_outb(cwaintmp,cwain_R_FIFO,0x1F << 1);
+    cwain_waitbusy(cwaintmp);
+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+    cwain_waitbusy(cwaintmp);
+    cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x1);
+    cwain_outb(cwaintmp,cwain_A_SUBCH_CFG,0x0);
+    cwain_outb(cwaintmp,cwain_A_CHANNEL,0x10 << 1);
+    cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
+
+    /* setup D-FIFO RX */
+    cwain_outb(cwaintmp,cwain_R_FIFO,(0x1F << 1) | 1);
+    cwain_waitbusy(cwaintmp);
+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+    cwain_waitbusy(cwaintmp);
+    cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x1);
+    cwain_outb(cwaintmp,cwain_A_SUBCH_CFG,0x0);
+    cwain_outb(cwaintmp,cwain_A_CHANNEL,(0x10 << 1) | 1);
+    cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
+
+    /* setup B-FIFOs TX */
+    /* map ts 1 to 15 to fifos 0 to 14 */
+    for (i=1; i<16 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,(i - 1) << 1);
+	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+	cwain_waitbusy(cwaintmp);
+	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
+	cwain_outb(cwaintmp,cwain_A_CHANNEL,i << 1);
+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
+    }
+    /* map ts 17 to 31 to fifos 15 to 29 */
+    for (i=17; i<32 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,(i - 2) << 1);
+	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+	cwain_waitbusy(cwaintmp);
+	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
+	cwain_outb(cwaintmp,cwain_A_CHANNEL,i << 1);
+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
+    }
+
+    /* setup B-FIFOs RX */
+    /* map ts 1 to 15 to fifos 0 to 14 */
+    for (i=1; i<16 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,((i-1) << 1) | 1);
+    	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+    	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
+    	cwain_outb(cwaintmp,cwain_A_CHANNEL,(i << 1) | 1);
+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
+    }
+    /* map ts 17 to 31 to fifos 15 to 29 */
+    for (i=17; i<32 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,((i-2) << 1) | 1);
+    	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
+    	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
+    	cwain_outb(cwaintmp,cwain_A_CHANNEL,(i << 1) | 1);
+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
+    }
+
+    if (debug)
+        printk(KERN_INFO "cwain: starting card %d span %d/%d.\n",cwaintmp->cardno,span->spanno,span->offset);
+
+    if (cwaincard->spans == 1) {
+	cwain_set_master(cwaincard, 0);
+    }
+    
+    /* setup E1 amplitude */
+    cwain_outb(cwaintmp,cwain_R_PWM_MD,0x20);
+    cwain_outb(cwaintmp,cwain_R_PWM0,0x50);
+    cwain_outb(cwaintmp,cwain_R_PWM1,0xff);
+
+    /* setup E1 transceiver */
+    cwain_outb(cwaintmp,cwain_R_TX_SL0,0xf8);  // R_TX_FR1
+    cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG0,0x00); /* semiautomatic mode */
+
+    cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG0,0x6); /* 0x26 */
+
+    if (cwaintmp->span.lineconfig & ZT_CONFIG_AMI) {
+	cwain_outb(cwaintmp,cwain_R_TX0,0x82);
+	cwain_outb(cwaintmp,cwain_R_RX0,0x02);
+    } else if (cwaintmp->span.lineconfig & ZT_CONFIG_HDB3) {
+	cwain_outb(cwaintmp,cwain_R_TX0,0x81);
+	cwain_outb(cwaintmp,cwain_R_RX0,0x01);
+    }
+
+    /* transmitter mode */
+    cwain_outb(cwaintmp,cwain_R_TX1,0x60); 
+
+    cwain_outb(cwaintmp,cwain_R_LOS0,0x10);
+    cwain_outb(cwaintmp,cwain_R_LOS1,0x10);
+
+    if (cwaintmp->span.lineconfig & ZT_CONFIG_CRC4) {
+	/* crc4 multiframe */
+	cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG1,0x31);
+//	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x41);
+	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x03);
+    } else {
+	/* doubleframe */
+	cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG1,0x0);
+//	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x40);
+	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x02);
+    }
+
+    
+    /* setup sync mode */    
+    if (cwaincard->syncs[span->offset] > 0) {
+	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x2);
+	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_OUT,0xe0);
+	/* layer 1, up! */
+	cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x11);
+    }
+    
+    cwaintmp->sync = 0;
+    cwaintmp->sync_sta = 0;
+    
+    /* enable irqs */
+    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;
+}
+
+static int ztcwain_shutdown(struct zt_span *span) {
+    struct zt_cwain_card *cwaincard = span->pvt;
+    struct zt_cwain *cwaintmp;
+    unsigned long flags;
+    int alreadyrunning;
+    int i=0;
+    
+    if (cwaincard == NULL) {
+	printk(KERN_CRIT "cwain: cwaincard == NULL!\n");
+	return 0;
+    }
+
+    cwaintmp = cwaincard->span[span->offset];
+    if (cwaintmp == NULL) {
+	printk(KERN_CRIT "cwain: cwaintmp == NULL!\n");
+	return 0;
+    }
+
+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+    
+    if (!alreadyrunning) {
+	return 0;
+    }
+    spin_lock_irqsave(&cwaintmp->lock,flags);
+
+//    printk(KERN_CRIT "cwain: stopping card %d span %d/%d.\n",cwaintmp->cardno,span->spanno,span->offset);
+
+    // turn off irqs for all fifos
+
+    /* disable FIFO TX */
+    for (i=0; i<0x20 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,i << 1);
+	cwain_waitbusy(cwaintmp);
+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
+    }
+
+    /* disable FIFO RX */
+    for (i=0; i<0x20 ; i++) {
+	cwain_outb(cwaintmp,cwain_R_FIFO,(i << 1) | 1);
+    	cwain_waitbusy(cwaintmp);
+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
+    }
+
+
+    /* Deactivate Layer 1 */
+    cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x10);
+
+    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
+//    cwain_outb(cwaintmp,cwain_R_IRQMSK_MISC, 0); 
+    cwain_inb(cwaintmp,cwain_R_STATUS);
+
+
+    span->flags &= ~ZT_FLAG_RUNNING;
+
+
+    spin_unlock_irqrestore(&cwaintmp->lock,flags);
+
+//    printk(KERN_CRIT "cwain: card %d span %d/%d down.\n",cwaintmp->cardno,span->spanno,span->offset);
+    return 0;
+}
+
+static int ztcwain_maint(struct zt_span *span, int cmd) {
+    return 0;
+}
+
+static int ztcwain_chanconfig(struct zt_chan *chan,int sigtype) {
+//    printk(KERN_INFO "chan_config sigtype=%d\n", sigtype);
+    return 0;
+}
+
+static int ztcwain_spanconfig(struct zt_span *span,struct zt_lineconfig *lc) {
+    struct zt_cwain_card *cwaincard = span->pvt;
+    span->lineconfig = lc->lineconfig;
+    span->syncsrc = lc->sync;
+
+    cwaincard->syncs[span->offset] = lc->sync;
+    cwaincard->syncsrc = -1;
+//    printk(KERN_INFO "span_config %d lineconfig=%d syncsrc=%d\n", span->spanno, lc->lineconfig, lc->sync);
+//    cwain_check_timing(cwaincard);
+    return 0;
+}
+
+static int ztcwain_initialize(struct zt_cwain *cwaintmp, struct zt_cwain_card *cwaincard, int offset) {
+    int i=0;
+    
+	memset(&cwaintmp->span,0,sizeof(struct zt_span)); // you never can tell...
+	sprintf(cwaintmp->span.name,"cwain/%d",cwaintmp->cardno);
+	switch (cwaintmp->type) {
+	    case 0xb553:
+		sprintf(cwaintmp->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d)",cwaintmp->cardno,cwaintmp->cardID);
+		break;
+	    case 0xb554:
+		sprintf(cwaintmp->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
+		break;
+	    default:
+		return -1;
+	}
+        cwaintmp->span.spanconfig = ztcwain_spanconfig;
+        cwaintmp->span.chanconfig = ztcwain_chanconfig;
+        cwaintmp->span.startup = ztcwain_startup;
+        cwaintmp->span.shutdown = ztcwain_shutdown;
+        cwaintmp->span.maint = ztcwain_maint;
+        cwaintmp->span.rbsbits = ztcwain_rbsbits;
+        cwaintmp->span.open = ztcwain_open;
+        cwaintmp->span.close = ztcwain_close;
+        cwaintmp->span.ioctl = ztcwain_ioctl;
+
+        cwaintmp->span.chans = cwaintmp->chans;
+        cwaintmp->span.channels = 31;
+        cwaintmp->span.deflaw = ZT_LAW_ALAW;
+        cwaintmp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_HDB3 | ZT_CONFIG_CCS; 
+        init_waitqueue_head(&cwaintmp->span.maintq);
+        cwaintmp->span.pvt = cwaincard;
+        cwaintmp->span.offset = offset;
+
+	for (i=0; i < cwaintmp->span.channels; i++) {
+	    memset(&(cwaintmp->chans[i]),0x0,sizeof(struct zt_chan));
+	    sprintf(cwaintmp->chans[i].name,"cwain%d/%d",cwain_span_count + 1,i + 1);
+	    cwaintmp->chans[i].pvt = cwaintmp;
+	    cwaintmp->chans[i].sigcap =  ZT_SIG_CLEAR;
+	    cwaintmp->chans[i].chanpos = i + 1; 
+	}
+
+	if (zt_register(&cwaintmp->span,0)) {
+	    printk(KERN_INFO "cwain: unable to register zaptel span!\n");
+	    return -1;
+	}
+//	 printk(KERN_INFO "cwain: registered zaptel span %d.\n",s+1);
+
+    return 0;
+}
+
+int cwain_reset_card(struct zt_cwain_card *cwaintmp) {
+    unsigned long flags;
+    int i = 0;
+
+    cwaintmp->irq = cwaintmp->span[0]->irq;
+    
+    if (cwaintmp->spans == 2) {
+	if (request_irq(cwaintmp->irq, cwain_interrupt, SA_INTERRUPT | SA_SHIRQ, "cwain2", cwaintmp)) {
+    	    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");
+	    return -1;
+	}
+    }
+
+    spin_lock_irqsave(&(cwaintmp->lock),flags);
+
+    for (i=0;i<cwaintmp->spans;i++) {
+	cwain_reset_span(cwaintmp->span[i]);
+    }
+
+    /* no master yet, force reelection */
+    cwaintmp->syncsrc = -1;
+    
+    /* set up the timer 1 khz, zaptel timing */
+    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, 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); 
+
+    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
+    return 0;
+}
+
+int cwain_find_spans(unsigned int pcidid) {
+    struct pci_dev *tmp;
+    struct zt_cwain *cwaintmp = NULL;
+    int i=0;
+    unsigned char dips=0;
+    int cid=0;
+    int modes=0;
+    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_cwain);
+    while (tmp != NULL) {
+	multi_cwain = tmp;	// skip this next time.
+
+	if (pci_enable_device(tmp)) {
+	    multi_cwain = NULL;
+	    return -1;
+	}
+
+	cwaintmp = kmalloc(sizeof(struct zt_cwain),GFP_KERNEL);
+	if (!cwaintmp) {
+	    printk(KERN_WARNING "cwain: unable to kmalloc!\n");
+	    pci_disable_device(tmp);
+	    multi_cwain = NULL;
+	    return -ENOMEM;
+	}
+	memset(cwaintmp, 0x0, sizeof(struct zt_cwain));
+	
+	spin_lock_init(&cwaintmp->lock);
+	cwaintmp->pcidev = tmp;
+	cwaintmp->pcibus = tmp->bus->number;
+	cwaintmp->pcidevfn = tmp->devfn; 
+
+
+	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;
+	    return -EIO;
+	}
+
+	if (!tmp->irq) {
+	    printk(KERN_WARNING "cwain: PCI device has no irq!\n");
+	    pci_disable_device(tmp);
+	    multi_cwain = NULL;
+	    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_phys, 256);
+			       
+	/* enable memio */
+	pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);	
+
+	/* disable interrupts */
+	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
+
+        if (((tmp->subsystem_device==0xb553) || (tmp->subsystem_device==0xb554))&& (pcidid == PCI_DEVICE_ID_CCD_E)) {
+	    dips = (cwain_inb(cwaintmp,cwain_R_GPI_IN0) >> 5);
+	    cid = 7;
+	    for (i=0;i<3;i++) {
+	        if ((dips & (1 << i)) != 0) {
+	    	cid -= (1 << (2-i));
+	        }
+	    }
+//		printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
+        } else {
+	    cid = 0xff;
+        }
+
+	if (ports == -1) {
+    	    if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_E)) {
+		modes = (cwain_inb(cwaintmp,cwain_R_GPI_IN0) >> 4) & 0x01;
+	    } else {
+		modes = 0; // assume TE mode
+	    }
+	} else {
+	    modes = ports >> cwain_span_count;
+	}
+
+
+	cwaintmp->cardID = cid;
+	cwaintmp->type = tmp->subsystem_device;
+
+	if ((modes & 1) != 0) {
+	    cwaintmp->nt_mode = 1;
+	} else {
+	    cwaintmp->nt_mode = 0;
+	}
+
+	cwain_register_span(cwaintmp);
+
+	tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_cwain);
+    }
+    return 0;
+}
+
+
+int cwain_sort_cards(void) {
+    int changed=0,tmpcardno;
+    struct zt_cwain_card *tmpcard,*tmpcard2;
+    spin_lock(&cwain_card_registerlock);
+    do {
+	changed = 0;
+	tmpcard = cwain_card_list;
+	while (tmpcard != NULL) {
+	    if (tmpcard->prev) {
+		if (tmpcard->prev->cardID > tmpcard->cardID) {
+		    tmpcardno = tmpcard->prev->cardno;
+		    tmpcard->prev->cardno = tmpcard->cardno; 
+		    tmpcard->cardno = tmpcardno;
+		
+		    tmpcard2 = tmpcard->prev;
+		    if (tmpcard2->prev) {
+			tmpcard2->prev->next = tmpcard;
+		    } else {
+			cwain_card_list = tmpcard;
+		    }
+		    if (tmpcard->next) {
+			tmpcard->next->prev = tmpcard2;
+		    } 
+		    tmpcard2->next = tmpcard->next;
+		    tmpcard->prev = tmpcard2->prev;
+		    tmpcard->next = tmpcard2;
+		    tmpcard2->prev = tmpcard;
+		    changed = 1;
+		    tmpcard = tmpcard2;
+		}
+	    }
+	    tmpcard = tmpcard->next;
+	}
+    } while (changed == 1);
+    spin_unlock(&cwain_card_registerlock);
+    return 0;
+}
+
+int cwain_zap_cards(void) {
+    struct zt_cwain_card *tmpcard = cwain_card_list;
+    int i=0;
+    int res=0;
+    while (tmpcard != NULL) {
+	for (i=0; i<tmpcard->spans; i++) {
+	    ztcwain_initialize(tmpcard->span[i], tmpcard, i);
+	}
+	res = cwain_reset_card(tmpcard);
+	tmpcard = tmpcard->next;
+    }
+    return res;
+}
+
+
+int init_module(void) {
+    multi_cwain = NULL;
+    cwain_find_spans(PCI_DEVICE_ID_CCD_E);
+    cwain_sort_cards();
+    cwain_zap_cards();
+    if (cwain_card_count == 0) {
+	printk(KERN_INFO "cwain: no cwain cards found.\n");
+    } else {
+	printk(KERN_INFO "cwain: %d cwain card(s) in this box, %d E1 ports total.\n", cwain_card_count, cwain_span_count);
+    }
+    return 0;
+}
+
+void cleanup_module(void) {
+    struct zt_cwain_card *tmpcard,*tmplist;
+    struct zt_cwain *tmpspan,*spanlist;
+    int i=0;
+    int j=0;
+    
+    tmplist = cwain_card_list;
+    tmpcard = NULL;
+    while (tmplist) {
+	tmpcard = tmplist;
+	tmplist = tmplist->next;
+
+	tmpcard->dead = 1;
+	cwain_shutdown_card(tmpcard);
+	kfree(tmpcard);
+	i++;
+    }
+
+    spanlist = cwain_span_list;
+    tmpspan = NULL;
+    while (spanlist) {
+	tmpspan = spanlist;
+	spanlist = spanlist->next;
+	kfree(tmpspan);
+	j++;
+    }
+    printk(KERN_INFO "cwain: shutdown %d spans, %d cwain cards.\n", j, i);
+}
+#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	

Added: zaptel/trunk/cwain/cwain.h
===================================================================
--- zaptel/trunk/cwain/cwain.h	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/cwain.h	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,245 @@
+#define cwain_FIFO_SIZE	128
+#define cwain_DFIFO_SIZE	4096
+#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;
+    unsigned int type;
+
+    /* lock to protect the structure */
+    spinlock_t lock;
+    int cardID;
+    unsigned char cardno;
+    
+    /* ticks and clicks, fish and chips */
+    unsigned int ticks;
+    unsigned int clicks;
+    unsigned char nt_mode;
+    unsigned char sync_sta;
+    unsigned char sync;
+    int syncmode;
+    
+    /* blinky blink */
+    unsigned char leds[4];
+
+    /* 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;
+    /* D chan buffer */
+    unsigned char drxbuf[cwain_DFIFO_SIZE];
+    unsigned char dtxbuf[cwain_DFIFO_SIZE];
+
+
+    /* zaptel resources */
+    struct zt_span span;
+    struct zt_chan chans[31];
+
+    /* more zaptel stuff */
+    unsigned int usecount;
+    int spantype;
+    int spanflags;
+
+    /* linked list */
+    struct zt_cwain *next;
+    struct zt_cwain *prev;
+
+} zt_cwain;
+
+typedef struct zt_cwain_card {
+    /* lock to protect the structure */
+    spinlock_t lock;
+
+    unsigned int spans;
+    unsigned int dead;
+    int cardID;
+    unsigned char cardno;
+    unsigned int ticks;
+
+    struct zt_cwain *span[2];
+    int syncsrc;
+    int syncs[2];
+    int master[2];
+    
+    unsigned int irq;   
+    unsigned int pcibus;
+
+    /* linked list */
+    struct zt_cwain_card *next;
+    struct zt_cwain_card *prev;
+} zt_cwain_card;
+
+#define cwain_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
+#define cwain_inb(a,b) (readb((a)->pci_io+(b)))
+
+#define cwain_outw(a,b,c) (writew((c),(a)->pci_io+(b)))
+#define cwain_inw(a,b) (readw((a)->pci_io+(b)))
+
+#define cwain_outdw(a,b,c) (writel((c),(a)->pci_io+(b)))
+#define cwain_indw(a,b) (readl((a)->pci_io+(b)))
+
+
+/* Write only registers */
+#define cwain_A_CH_MSK		0xF4
+#define cwain_A_CHANNEL 	0xFC
+#define cwain_A_CON_HDLC	0xFA
+#define cwain_A_CONF		0xD1
+#define cwain_A_FIFO_SEQ	0xFD
+#define cwain_R_INC_RES_FIFO	0x0E
+#define cwain_A_IRQ_MSK		0xFF
+#define cwain_A_SL_CFG		0xD0
+#define cwain_A_SUBCH_CFG	0xFB
+#define cwain_R_BERT_WD_MD	0x1B
+#define cwain_R_BRG_PCM_CFG	0x02
+#define cwain_R_CIRM		0x00
+#define cwain_R_CONF_EN		0x18
+#define cwain_R_CTRL		0x01
+#define cwain_R_DTMF		0x1C
+#define cwain_R_DTMF_N		0x1D
+#define cwain_R_E1_WR_STA	0x20
+#define cwain_R_FIFO_MD		0x0D
+#define cwain_R_FIFO		0x0F
+#define cwain_R_FIRST_FIFO	0x0B
+#define cwain_R_FSM_IDX		0x0F
+#define cwain_R_GPIO_EN0	0x42
+#define cwain_R_GPIO_EN1	0x43
+#define cwain_R_GPIO_OUT0	0x40
+#define cwain_R_GPIO_OUT1	0x41
+#define cwain_R_GPIO_SEL	0x44
+#define cwain_R_IRQ_CTRL	0x13
+#define cwain_R_IRQMSK_MISC	0x11
+#define cwain_R_JATT_CFG	0x2F
+#define cwain_R_LOS0		0x22
+#define cwain_R_LOS1		0x23
+#define cwain_R_PCM_MD0		0x14
+#define cwain_R_PCM_MD1		0x15
+#define cwain_R_PCM_MD2		0x15
+#define cwain_R_PWM_MD		0x46
+#define cwain_R_PWM0		0x38
+#define cwain_R_PWM1		0x39
+#define cwain_R_RAM_ADDR0	0x08
+#define cwain_R_RAM_ADDR1	0x09
+#define cwain_R_RAM_ADDR2	0x0A
+#define cwain_R_RAM_MISC	0x0C
+#define cwain_R_RX_OFFS		0x30
+#define cwain_R_RX_SL0_CFG0	0x25
+#define cwain_R_RX_SL0_CFG1	0x26
+#define cwain_R_RX0		0x24
+#define cwain_R_SH0H		0x15
+#define cwain_R_SH0L		0x15
+#define cwain_R_SH1H		0x15
+#define cwain_R_SH1L		0x15
+#define cwain_R_SL_SEL0		0x15
+#define cwain_R_SL_SEL1		0x15
+#define cwain_R_SL_SEL2		0x15
+#define cwain_R_SL_SEL3		0x15
+#define cwain_R_SL_SEL4		0x15
+#define cwain_R_SL_SEL5		0x15
+#define cwain_R_SL_SEL6		0x15
+#define cwain_R_SL_SEL7		0x15
+#define cwain_R_SLOT		0x10
+#define cwain_R_SYNC_CTRL	0x35
+#define cwain_R_SYNC_OUT	0x31
+#define cwain_R_TI_WD		0x1A
+#define cwain_R_TX_OFFS		0x34
+#define cwain_R_TX_SL0_CFG0	0x2C
+#define cwain_R_TX_SL0_CFG1	0x2E
+#define cwain_R_TX_SL0		0x2D
+#define cwain_R_TX0		0x28
+#define cwain_R_TX1		0x29
+
+#define cwain_R_TX_FR0		0x2C
+#define cwain_R_TX_FR1		0x2D
+#define cwain_R_TX_FR2		0x2E
+
+#define cwain_R_RX_FR0		0x25
+#define cwain_R_RX_FR1		0x26
+
+/* Read only registers */
+#define cwain_A_F1		0x0C
+#define cwain_A_F12		0x0C
+#define cwain_A_F2		0x0D
+#define cwain_A_Z1		0x04
+#define cwain_A_Z12		0x04
+#define cwain_A_Z1H		0x05
+#define cwain_A_Z1L		0x04
+#define cwain_A_Z2		0x06
+#define cwain_A_Z2H		0x07
+#define cwain_A_Z2L		0x06
+#define cwain_R_BERT_ECH	0x1B
+#define cwain_R_BERT_ECL	0x1A
+#define cwain_R_BERT_STA	0x17
+#define cwain_R_CHIP_ID		0x16
+#define cwain_R_CHIP_RV		0x1F
+#define cwain_R_CONF_OFLOW	0x14
+#define cwain_R_CRC_ECH		0x35
+#define cwain_R_CRC_ECL		0x34
+#define cwain_R_E_ECH		0x37
+#define cwain_R_E_ECL		0x36
+#define cwain_R_E1_RD_STA	0x20
+#define cwain_R_F0_CNTH		0x19
+#define cwain_R_F0_CNTL		0x18
+#define cwain_R_FAS_ECH		0x31
+#define cwain_R_FAS_ECL		0x30
+#define cwain_R_GPI_IN0		0x44
+#define cwain_R_GPI_IN1		0x45
+#define cwain_R_GPI_IN2		0x46
+#define cwain_R_GPI_IN3		0x47
+#define cwain_R_GPIO_IN0	0x40
+#define cwain_R_GPIO_IN1	0x41
+#define cwain_R_INT_DATA	0x88
+#define cwain_R_IRQ_FIFO_BL0	0xC8
+#define cwain_R_IRQ_FIFO_BL1	0xC9
+#define cwain_R_IRQ_FIFO_BL2	0xCA
+#define cwain_R_IRQ_FIFO_BL3	0xCB
+#define cwain_R_IRQ_FIFO_BL4	0xCC
+#define cwain_R_IRQ_FIFO_BL5	0xCD
+#define cwain_R_IRQ_FIFO_BL6	0xCE
+#define cwain_R_IRQ_FIFO_BL7	0xCF
+#define cwain_R_IRQ_MISC	0x11
+#define cwain_R_IRQ_OVIEW	0x10
+#define cwain_R_JATT_STA	0x2B
+#define cwain_R_RAM_USE		0x15
+#define cwain_R_RX_SL0_0	0x25
+#define cwain_R_RX_SL0_1	0x26
+#define cwain_R_RX_SL0_2	0x27
+#define cwain_R_SA6_VAL13_ECH	0x39
+#define cwain_R_SA6_VAL13_ECL	0x38
+#define cwain_R_SA6_VAL23_ECH	0x3B
+#define cwain_R_SA6_VAL23_ECL	0x3A
+#define cwain_R_SLIP		0x2C
+#define cwain_R_STATUS		0x1C
+#define cwain_R_SYNC_STA	0x24
+#define cwain_R_VIO_ECH		0x33
+#define cwain_R_VIO_ECL		0x32
+
+
+/* Read/Write registers */
+#define cwain_A_FIFO_DATA0_NOINC	0x84
+#define cwain_A_FIFO_DATA0	0x80
+#define cwain_A_FIFO_DATA1_NOINC	0x84
+#define cwain_A_FIFO_DATA1	0x80
+#define cwain_A_FIFO_DATA2_NOINC	0x84
+#define cwain_A_FIFO_DATA2	0x80
+#define cwain_R_RAM_DATA	0xC0
+
+#define PCI_DEVICE_ID_CCD_E	0x30b1
+
+#define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
+#define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
+

Added: zaptel/trunk/cwain/zapata.conf
===================================================================
--- zaptel/trunk/cwain/zapata.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/zapata.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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
+

Added: zaptel/trunk/cwain/zapata.conf.doubleE1
===================================================================
--- zaptel/trunk/cwain/zapata.conf.doubleE1	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/zapata.conf.doubleE1	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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
+

Added: zaptel/trunk/cwain/zaptel.conf
===================================================================
--- zaptel/trunk/cwain/zaptel.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/zaptel.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,11 @@
+loadzone=nl
+defaultzone=nl
+span=1,2,3,ccs,hdb3,crc4
+
+alaw=1-31
+
+bchan=1-15
+dchan=16
+bchan=17-31
+
+

Added: zaptel/trunk/cwain/zaptel.conf.doubleE1
===================================================================
--- zaptel/trunk/cwain/zaptel.conf.doubleE1	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/cwain/zaptel.conf.doubleE1	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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

Modified: zaptel/trunk/debian/changelog
===================================================================
--- zaptel/trunk/debian/changelog	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/debian/changelog	2006-06-19 20:27:22 UTC (rev 1918)
@@ -5,6 +5,11 @@
   [ Kilian Krause ]
   * Add vzaphfc driver (enhanced zaphfc) by Jens Wilke.
 
+  [ Tzafrir Cohen ]
+  * Separating ZapBRI modules to directories, rather than patches
+  * Example configs moved from zaptel-source to zaptel
+  * Removing some unneeded dirs from zaptel-source
+
  -- Kilian Krause <kilian at debian.org>  Sat, 17 Jun 2006 16:05:32 +0200
 
 zaptel (1:1.2.6-2) unstable; urgency=high

Modified: zaptel/trunk/debian/patches/bristuff.dpatch
===================================================================
--- zaptel/trunk/debian/patches/bristuff.dpatch	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/debian/patches/bristuff.dpatch	2006-06-19 20:27:22 UTC (rev 1918)
@@ -2,6847 +2,13 @@
 ## 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, ztgsm) and zaptel.patch from
-## DP: the bristuff patch by Klaus-Peter Junghanns. Version 0.3.0-PRE1q
+## DP: This is the patch zaptel.patch from bristuff, with the Makefile
+## DP: patch removed. Version: 0.3.0-PRE1q
 
 @DPATCH@
-diff -urNad zaptel-1.2.6/cwain/cwain.c /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/cwain.c
---- zaptel-1.2.6/cwain/cwain.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/cwain.c	2006-04-25 22:15:34.000000000 +0300
-@@ -0,0 +1,1629 @@
-+/*
-+ * cwain.c - Zaptel driver for the Junghanns.NET E1 card
-+ *
-+ * c.w.a.i.n. == card without an interesting name
-+ *
-+ * single/double E1 board
-+ *
-+ * Copyright (C) 2004, 2005 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 "cwain.h"
-+
-+#if CONFIG_PCI
-+
-+static int ports=-1; /* autodetect */
-+static int debug=0;
-+static struct zt_cwain *cwain_span_list = NULL;
-+static int cwain_span_count = 0;
-+static struct zt_cwain_card *cwain_card_list = NULL;
-+static int cwain_card_count = 0;
-+static struct pci_dev *multi_cwain = NULL;
-+static spinlock_t cwain_span_registerlock = SPIN_LOCK_UNLOCKED;
-+static spinlock_t cwain_card_registerlock = SPIN_LOCK_UNLOCKED;
-+
-+static int ztcwain_shutdown(struct zt_span *span);
-+
-+int cwain_waitbusy(struct zt_cwain *cwaintmp) {
-+    int x=1000;
-+    while (x-- && (cwain_inb(cwaintmp,cwain_R_STATUS) & 1));
-+    if (x < 0) {
-+	printk(KERN_CRIT "cwain: really busy waiting!\n");
-+	return -1;
-+    } else {
-+	if ((x < 990) && (cwaintmp->ticks > 500)) {
-+	    printk(KERN_CRIT "cwain: waited %d\n", 1000 - x);
-+	}
-+	return 0;
-+    }
-+}
-+
-+void cwain_unregister_zap_span(struct zt_cwain *cwainspan) {
-+    if (!cwainspan) {
-+	printk(KERN_INFO "cwain: shutting down NULL span!\n");
-+	return;
-+    }
-+    if(cwainspan->span.flags & ZT_FLAG_RUNNING) {
-+        ztcwain_shutdown(&cwainspan->span);
-+        if (debug)
-+            printk(KERN_INFO "cwain: shutdown span %d.\n",cwainspan->cardno);
-+    }
-+    if(cwainspan->span.flags & ZT_FLAG_REGISTERED) {
-+        zt_unregister(&cwainspan->span);
-+        if (debug)
-+    	printk(KERN_INFO "cwain: unregistered span %d.\n",cwainspan->cardno);
-+    }
-+}
-+
-+void cwain_shutdown_span(struct zt_cwain *cwainspan) {
-+    
-+    if (!cwainspan) {
-+	printk(KERN_INFO "cwain: shutting down NULL span!\n");
-+	return;
-+    }
-+
-+    if (cwainspan->pci_io == NULL) {
-+	return;
-+    }
-+
-+    if (debug)
-+	printk(KERN_INFO "cwain: shutting down span %d (cardID %d) at %p.\n",cwainspan->cardno,cwainspan->cardID,cwainspan->pci_io);
-+
-+    // turn off irqs
-+
-+    // softreset
-+    cwain_outb(cwainspan,cwain_R_CIRM,0x8);
-+    cwain_outb(cwainspan,cwain_R_CIRM,0x0); 
-+    cwain_waitbusy(cwainspan);
-+
-+    cwain_outb(cwainspan,cwain_R_IRQMSK_MISC, 0); 
-+    cwain_outb(cwainspan,cwain_R_IRQ_CTRL, 0); 
-+
-+    pci_write_config_word(cwainspan->pcidev, PCI_COMMAND, 0);	// disable memio
-+
-+    if (cwainspan->pcidev != NULL) {
-+        pci_disable_device(cwainspan->pcidev);
-+	cwainspan->pcidev = NULL;
-+    }
-+
-+//    iounmap((void *) cwainspan->pci_io);
-+//    cwainspan->pci_io = NULL;
-+}
-+
-+void cwain_shutdown_card(struct zt_cwain_card *cwaintmp) {
-+    unsigned long flags = 0;
-+    int i = 0;
-+    
-+    if (!cwaintmp) {
-+	printk(KERN_INFO "cwain: shutting down NULL card!\n");
-+	return;
-+    }
-+
-+    for (i=0;i<cwaintmp->spans;i++) {
-+	cwain_unregister_zap_span(cwaintmp->span[i]);
-+    }
-+
-+    spin_lock_irqsave(&cwaintmp->lock,flags);
-+
-+    // turn off irqs
-+    cwain_outb(cwaintmp->span[0],cwain_R_IRQ_CTRL, 0); 
-+    cwain_outb(cwaintmp->span[0],cwain_R_IRQMSK_MISC, 0); 
-+
-+    for (i=0;i<cwaintmp->spans;i++) {
-+	cwain_shutdown_span(cwaintmp->span[i]);
-+    }
-+    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);
-+}
-+
-+void cwain_doLEDs(struct zt_cwain *cwaintmp) {
-+    /*
-+     O1 O3 (red)
-+     O2 O4 (green)
-+    */
-+    if (!(cwaintmp->span.flags & ZT_FLAG_RUNNING)) {
-+	return;
-+    }
-+    if ((cwaintmp->type == 0xb553) || (cwaintmp->type == 0xb554)) {
-+	/* sync status */
-+	if (((cwaintmp->sync_sta & 0x07) == 0x07) && cwaintmp->sync) {
-+	    cwaintmp->leds[0] = 1;    
-+	    cwaintmp->leds[1] = 0;    
-+	} else {
-+	    cwaintmp->leds[0] = 0;    
-+	    cwaintmp->leds[1] = 1;    
-+	}
-+	/* multiframe alignment */
-+	if ((cwaintmp->sync_sta & 0x20) == 0x20) {
-+    	    cwaintmp->leds[2] = 1;    
-+	    cwaintmp->leds[3] = 0;    
-+	} else {
-+	    if ((cwaintmp->span.lineconfig & ZT_CONFIG_CRC4) && cwaintmp->sync) {
-+		/* CRC4 requested */
-+		cwaintmp->leds[2] = 0;    
-+		cwaintmp->leds[3] = 1;    
-+	    } else {
-+		/* no CRC4, disable 3 and 4 */
-+		cwaintmp->leds[2] = 1;    
-+		cwaintmp->leds[3] = 1;    
-+	    }
-+	}
-+	cwain_outb(cwaintmp,cwain_R_GPIO_OUT1,(cwaintmp->leds[0] | (cwaintmp->leds[1] << 1) | (cwaintmp->leds[2] << 2) | (cwaintmp->leds[3] << 3)));
-+    }
-+}
-+
-+void cwain_reset_span(struct zt_cwain *cwaintmp) {
-+    int i = 0;
-+    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);
-+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
-+    cwain_waitbusy(cwaintmp);
-+
-+    /* PCM reset */
-+    cwain_outb(cwaintmp,cwain_R_CIRM,0x20);
-+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
-+    cwain_waitbusy(cwaintmp);
-+
-+    for (i=0; i<128; i++) {
-+	cwain_outb(cwaintmp,cwain_R_SLOT, i);
-+	cwain_outb(cwaintmp,cwain_A_SL_CFG, 0x0);
-+    }
-+    
-+    /* E1 reset */
-+    cwain_outb(cwaintmp,cwain_R_CIRM,0x40);
-+    cwain_outb(cwaintmp,cwain_R_CIRM,0x0); 
-+    cwain_waitbusy(cwaintmp);
-+
-+    /* 128 byte B chans, 4096 byte D chans */
-+    cwain_outb(cwaintmp,cwain_R_FIFO_MD,0x36);
-+    cwain_outb(cwaintmp,cwain_R_BRG_PCM_CFG,0x0); 
-+    cwain_outb(cwaintmp,cwain_R_CTRL,0x0); 
-+
-+    /* no blinky blink */
-+    cwain_outb(cwaintmp,cwain_R_GPIO_SEL,0x20 | 0x10);
-+    cwain_outb(cwaintmp,cwain_R_GPIO_EN1,0x0f);
-+    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;    
-+    cwaintmp->leds[1] = 1;    
-+    cwaintmp->leds[2] = 1;    
-+    cwaintmp->leds[3] = 1;    
-+    
-+    cwaintmp->ticks = 0;
-+    cwaintmp->clicks = 0;
-+}
-+
-+struct zt_cwain_card *cwain_get_card(unsigned int pcibus) {
-+    struct zt_cwain_card *cwaintmp = cwain_card_list;
-+    spin_lock(&cwain_card_registerlock);
-+    while (cwaintmp) {
-+	if (cwaintmp->pcibus == pcibus) {
-+	    break;
-+	}
-+	cwaintmp = cwaintmp->next;
-+    }
-+    spin_unlock(&cwain_card_registerlock);
-+    return cwaintmp;
-+}
-+
-+
-+void cwain_register_card(struct zt_cwain_card *cwaincard) {
-+    spin_lock(&cwain_card_registerlock);
-+    if (cwaincard != NULL) {
-+	cwaincard->prev = NULL;
-+	cwaincard->next = cwain_card_list;
-+	if (cwain_card_list) {
-+	    cwain_card_list->prev = cwaincard;
-+	}
-+	cwain_card_list = cwaincard;
-+	cwain_card_count++;
-+    } else {
-+	printk(KERN_INFO "cwain: trying to register NULL card.\n");
-+    }
-+    spin_unlock(&cwain_card_registerlock);
-+}
-+
-+int cwain_register_span(struct zt_cwain *cwainspan) {
-+    struct zt_cwain_card *cwaintmp;
-+    spin_lock(&cwain_span_registerlock);
-+    if (cwainspan != NULL) {
-+	cwainspan->prev = NULL;
-+	cwainspan->next = cwain_span_list;
-+	if (cwain_span_list) {
-+	    cwain_span_list->prev = cwainspan;
-+	}
-+	cwain_span_list = cwainspan;
-+	cwainspan->cardno = ++cwain_span_count;
-+    } else {
-+	printk(KERN_INFO "cwain: trying to register NULL span.\n");
-+    }
-+    spin_unlock(&cwain_span_registerlock);
-+
-+    if (cwainspan->type == 0xb553) {
-+	cwaintmp = kmalloc(sizeof(struct zt_cwain_card),GFP_KERNEL);
-+	if (!cwaintmp) {
-+	    printk(KERN_WARNING "cwain: unable to kmalloc!\n");
-+	    return -1;
-+	}
-+	memset(cwaintmp, 0x0, sizeof(struct zt_cwain_card));
-+	
-+	spin_lock_init(&cwaintmp->lock);
-+	cwaintmp->pcibus = cwainspan->pcibus;
-+	cwaintmp->span[0] = cwainspan;
-+	cwaintmp->syncs[0] = -1;
-+	cwaintmp->spans = 1;
-+	cwaintmp->cardID = cwainspan->cardID;
-+	cwain_register_card(cwaintmp);
-+	printk(KERN_INFO
-+	        "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);
-+	if (!cwaintmp) {
-+	    cwaintmp = kmalloc(sizeof(struct zt_cwain_card),GFP_KERNEL);
-+	    if (!cwaintmp) {
-+		printk(KERN_WARNING "cwain: unable to kmalloc!\n");
-+	        return -1;
-+	    }
-+	    memset(cwaintmp, 0x0, sizeof(struct zt_cwain_card));
-+	
-+	    spin_lock_init(&cwaintmp->lock);
-+	    cwaintmp->pcibus = cwainspan->pcibus;
-+	    cwaintmp->spans = cwainspan->type - 46419;
-+	    cwaintmp->span[0] = cwainspan;
-+	    cwaintmp->cardID = cwainspan->cardID;
-+	    cwaintmp->syncs[0] = -1;
-+	    cwain_register_card(cwaintmp);
-+	} else {
-+	    cwaintmp->spans = cwainspan->type - 46418;
-+	    if (cwainspan->cardID < cwaintmp->cardID) {
-+		cwaintmp->cardID = cwainspan->cardID;
-+		cwaintmp->span[1] = cwaintmp->span[0];
-+		cwaintmp->syncs[1] = cwaintmp->syncs[0];
-+	        cwaintmp->span[0] = cwainspan;
-+	    } else {
-+	        cwaintmp->span[1] = cwainspan;
-+		cwaintmp->syncs[1] = -1;
-+	    }
-+	    printk(KERN_INFO
-+	        "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);
-+	}
-+    }
-+    return 0;
-+}
-+
-+static int cwain_dfifo_tx(struct zt_cwain *cwaintmp) {
-+    int chan = 15;
-+    int x=0;
-+    char fifo = 0;
-+
-+    fifo = 0x1F;
-+
-+    if (cwaintmp->chans[chan].bytes2transmit < 1) {
-+	return 0;
-+    } else {
-+	/* select fifo */
-+	cwain_outb(cwaintmp,cwain_R_FIFO,fifo << 1);    
-+	cwain_waitbusy(cwaintmp);
-+    
-+	if (debug)
-+	    printk(KERN_INFO "cwain: card %d TX [ ", cwaintmp->cardno);
-+	/* copy frame to fifo */
-+    	for (x=0;x<cwaintmp->chans[chan].bytes2transmit;x++) {
-+	    if (debug)
-+	        printk("%#x ",cwaintmp->dtxbuf[x]);
-+    	    cwain_outb(cwaintmp,cwain_A_FIFO_DATA0,cwaintmp->dtxbuf[x]);
-+	}
-+	if (debug)
-+	    printk("]\n");
-+	if (debug)
-+    	    printk(KERN_INFO "ztx %d bytes\n",cwaintmp->chans[chan].bytes2transmit);
-+
-+	if (cwaintmp->chans[chan].eoftx == 1) {
-+	    /* transmit HDLC frame */
-+    	    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x1);    
-+    	    cwain_waitbusy(cwaintmp);
-+	}
-+    }
-+    return 0;
-+}
-+
-+static int cwain_fifo_tx(struct zt_cwain *cwaintmp, char fifo) {
-+    int chan,f;
-+    if (fifo >= 15) {
-+	chan = fifo;
-+    } else {
-+	chan = fifo;
-+    }
-+    /* select fifo */
-+    cwain_outb(cwaintmp,cwain_R_FIFO,0x80 | (fifo << 1));    
-+    cwain_waitbusy(cwaintmp);
-+    
-+    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;
-+}
-+
-+static int cwain_dfifo_rx(struct zt_cwain *cwaintmp) {
-+    int chan = 15;
-+    unsigned char f1=1,f2=1,data,stat;
-+    unsigned char of1=0,of2=0;
-+    int len,i;
-+    unsigned short z1=1,z2=1;
-+    unsigned short oz1=0,oz2=0;
-+    char fifo = 0;
-+
-+    fifo = 0x1F;
-+    
-+    /* select fifo */
-+    cwain_outb(cwaintmp,cwain_R_FIFO,(fifo << 1) | 1);    
-+    cwain_waitbusy(cwaintmp);
-+    
-+    while ((oz1 != z1) && (oz2 != z2)) {
-+        oz1 = z1;
-+        oz2 = z2;
-+    	z1 = cwain_inw(cwaintmp,cwain_A_Z1) & 0xfff;
-+	z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0xfff;
-+    }
-+    
-+    len = z1-(z2 & 0xfff);
-+    if (len < 0) {
-+        len += cwain_DFIFO_SIZE;
-+    }
-+
-+    while ((of1 != f1) && (of2 != f2)) {
-+        of1 = f1;
-+        of2 = f2;
-+        f1 = cwain_inb(cwaintmp,cwain_A_F1) & 0xf;
-+        f2 = cwain_inb(cwaintmp,cwain_A_F2) & 0xf;
-+    }
-+
-+    if (len > cwain_DFIFO_SIZE) {
-+	printk(KERN_INFO "\ncwain: buffer overflow in D channel RX!\n");
-+	cwaintmp->chans[chan].bytes2receive = 0;
-+	cwaintmp->chans[chan].eofrx = 0;
-+    } else {
-+	if (debug) printk(KERN_INFO "cwain: card %d RX [ ", cwaintmp->cardno);
-+	for (i=0; i<len; i++) {
-+    	    data = cwain_inb(cwaintmp,cwain_A_FIFO_DATA0);
-+	    cwaintmp->drxbuf[i] = data;
-+	    if (debug) printk("%#x ",data);
-+	}
-+	if (debug) printk("] %d bytes\n", i);
-+	cwaintmp->chans[chan].bytes2receive = i;
-+	cwaintmp->chans[chan].eofrx = 1;
-+    }
-+
-+    stat = cwain_inb(cwaintmp,cwain_A_FIFO_DATA0);
-+    if (stat != 0x0) {
-+	// bad CRC, skip it
-+	if (cwaintmp->sync) {
-+	    printk(KERN_INFO "cwain: BAD CRC for hdlc frame on card %d (cardID %d) stat %#x\n",cwaintmp->cardno, cwaintmp->cardID, stat);
-+	}
-+	cwaintmp->chans[chan].bytes2receive = 0;
-+	cwaintmp->chans[chan].eofrx = 0;
-+//	    zt_qevent_nolock(&cwaintmp->spans[stport].chans[chan], ZT_EVENT_BADFCS);
-+    }
-+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x1);    
-+    cwain_waitbusy(cwaintmp);
-+
-+    /* frame received */
-+    cwaintmp->drx--;
-+    return 0;
-+}
-+
-+
-+static int cwain_fifo_rx(struct zt_cwain *cwaintmp, char fifo) {
-+    int chan;
-+    unsigned int data;
-+    int len,i,f,flen = 0;
-+    unsigned short z1=1,z2=1;
-+    unsigned short oz1=0,oz2=0;
-+    int mumbojumbo=0;
-+    int x = 1000;
-+
-+    chan = fifo;
-+
-+    // select rx fifo
-+    
-+	// no hdlc, transparent data
-+	cwain_outb(cwaintmp,cwain_R_FIFO,0x80 | (fifo << 1) | 1);    
-+        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) & 0x7f;
-+    	    z2 = cwain_inw(cwaintmp,cwain_A_Z2) & 0x7f;
-+	}
-+	if (x < 500) {
-+	    printk(KERN_CRIT "cwain: prevented endless loop\n");
-+	}
-+    
-+	if (mumbojumbo > 0) {
-+	    for (i=0;i<(mumbojumbo/4);i++) {
-+    		data = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
-+	    }
-+	    cwaintmp->clicks++;
-+	}
-+	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 {
-+	    for (f=0;f<(cwain_FRAME_SIZE / 4);f++) {
-+		*((unsigned int *) &cwaintmp->frxbuf[chan][f*4]) = cwain_indw(cwaintmp,cwain_A_FIFO_DATA0);
-+	    }
-+	}
-+
-+
-+	/* 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);    
-+    return 0;
-+}
-+
-+void cwain_set_master(struct zt_cwain_card *cwaintmp, int span) {
-+    int i=0;
-+
-+    if (cwaintmp->syncsrc == span) return;
-+    
-+    for (i=0; i < cwaintmp->spans; i++) {
-+	if (i != span) {
-+	    if (cwaintmp->syncs[i] > 0) {
-+		/* enable PCM slave mode, PCM32, synced to E1 receive */
-+    		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD0, 0x90);
-+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD1, 0x0);
-+		cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA0);
-+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD2, 0x00);
-+	    } else {
-+		/* enable PCM slave mode, PCM32 */
-+    		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD0, 0x90);
-+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD1, 0x0);
-+		cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA0);
-+		cwain_outb(cwaintmp->span[i],cwain_R_PCM_MD2, 0x00);
-+	    }
-+	    cwaintmp->master[i] = 0;
-+	    cwaintmp->span[i]->span.syncsrc = 0;
-+	}
-+    }
-+
-+    if (cwaintmp->syncs[span] > 0) {
-+        /* enable PCM master mode, PCM32, synced to E1 receive */
-+	if (debug)
-+	    printk(KERN_INFO "cwain: cardID %d span %d, PCM master E1 sync\n", cwaintmp->cardID, span);
-+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0x91);
-+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD1, 0x0);
-+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA1);
-+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD2, 0x00);
-+	cwaintmp->span[span]->span.syncsrc = 1;
-+    } else {
-+        /* enable PCM master mode, PCM32, free running */
-+	if (debug)
-+	    printk(KERN_INFO "cwain: cardID %d span %d, PCM master\n", cwaintmp->cardID, span);
-+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0x91);
-+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD1, 0x0);
-+	cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD0, 0xA1);
-+        cwain_outb(cwaintmp->span[span],cwain_R_PCM_MD2, 0x04);
-+	cwaintmp->span[span]->span.syncsrc = 0;
-+    }
-+    
-+    cwaintmp->master[span] = 1;
-+    cwaintmp->syncsrc = span;
-+}
-+
-+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->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;
-+		}
-+	    } else {
-+	        bestsync = i;
-+	    }
-+	}
-+    }
-+
-+    if (cwaintmp->syncsrc >= 0) {
-+	if (debug > 3)
-+	    printk(KERN_INFO "cwain: bestsync %d cwaintmp->syncsrc %d\n", bestsync, cwaintmp->syncsrc);
-+	
-+	if (bestsync == cwaintmp->syncsrc) {
-+	    if (debug > 3)
-+		printk(KERN_INFO "cwain: already on best syncsrc %d\n", bestsync);
-+	    return;
-+	}
-+
-+	/* if we have a better syncsrc */
-+	if (bestsync < cwaintmp->spans) {
-+	    if (debug)
-+		printk(KERN_INFO "cwain: found better syncsrc %d\n", bestsync);
-+	    cwain_set_master(cwaintmp, bestsync);
-+	    return;		    
-+	}
-+    }
-+
-+    /* if reelection failed, find internal sync source */
-+    if (cwaintmp->syncsrc == -1) {
-+	/* no master yet */
-+	if (debug > 3)
-+	    printk(KERN_INFO "cwain: no clocksource found cardID %d\n", cwaintmp->cardID);
-+	for (i=0; i < cwaintmp->spans; i++) {
-+	    /* find the first internal source */
-+	    if (debug > 3)
-+	        printk(KERN_INFO "cwain: cwaintmp->syncs[%d] = %d\n", i, cwaintmp->syncs[i]);
-+	    if (cwaintmp->syncs[i] == 0) {
-+		if (debug)
-+		    printk(KERN_INFO "cwain: using internal clock of span %d\n", i);
-+		cwain_set_master(cwaintmp, i);
-+		return;
-+	    }
-+	}
-+    }
-+
-+    /* if we have no internal sync source the only thing we can do is to enable any of the possible sync sources*/
-+    if (cwaintmp->syncsrc == -1) {
-+	/* find the first possible sync source with framing */
-+        for (i=0; i < cwaintmp->spans; i++) {
-+	    if (cwaintmp->syncs[i] > 0) {
-+		if (debug)
-+		    printk(KERN_INFO "cwain: desperately using clock of span %d\n", i);
-+		cwain_set_master(cwaintmp, i);
-+		break;
-+	    }
-+	}
-+    }
-+}
-+
-+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... */
-+        zt_transmit(&cwaintmp->span);
-+	/* B chans 1-15 mapped to fifos 0-14 */
-+	/* B chans 17-31 mapped to fifos 15-29 */
-+	for (fifo=0; fifo < 30; 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);
-+	}
-+
-+        cwaintmp->chans[15].bytes2receive = 0;
-+	cwaintmp->chans[15].bytes2transmit = 0;
-+	cwaintmp->chans[15].eofrx = 0;
-+	cwaintmp->chans[15].eoftx = 0;
-+
-+	for (fifo=0; fifo < 30; 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 */
-+	if ((cwaintmp->drx > 0) && cwaintmp->sync){
-+	    if (debug > 2)
-+	    	printk(KERN_CRIT "drx = %d\n", cwaintmp->drx);
-+	    cwain_dfifo_rx(cwaintmp);
-+	}
-+	/* oh zaptel! thou shall receive! */
-+	zt_receive(&(cwaintmp->span));
-+    }
-+}
-+
-+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 res;
-+    }
-+
-+    sync_sta = cwain_inb(cwainspan, cwain_R_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 (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;
-+	    }
-+	} 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);
-+		}
-+		sync_ok = 0x07;
-+	    } else {
-+		sync_ok = 0x00;
-+	    }
-+	}
-+
-+	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);
-+	}
-+
-+	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);
-+	
-+	    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.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;
-+	}
-+	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);
-+    }
-+    return res;
-+}
-+
-+int cwain_isr_fifo(struct zt_cwain *cwainspan, unsigned char status) {
-+    unsigned char irq_foview,fi;
-+
-+    if (status & 0x80) {
-+	/* fifo irq */
-+	irq_foview = cwain_inb(cwainspan,cwain_R_IRQ_OVIEW);
-+	if (irq_foview & 0x80) {
-+	    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 cardID %d\n", cwainspan->cardID);
-+		cwainspan->drx += 1;		
-+	    }
-+	}
-+	return 1;
-+    }
-+    return 0;
-+}
-+
-+#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 = 0;
-+#ifndef RELAXED_LOCKING    
-+    unsigned long flags;
-+#endif
-+    int i = 0;
-+    int l1event = 0;
-+    
-+    if (!cwaintmp || cwaintmp->dead) {
-+#ifdef LINUX26
-+		return IRQ_NONE;
-+#else
-+		return;
-+#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;
-+
-+    for (i=0;i<cwaintmp->spans;i++) {
-+	if (i == 0) {
-+	    status_tmp = status;
-+	} else {
-+	    status_tmp = cwain_inb(cwaintmp->span[i],cwain_R_STATUS);
-+	    status2 = status_tmp;
-+	}
-+	cwain_isr_fifo(cwaintmp->span[i], status_tmp);
-+    }
-+
-+    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
-+		return;
-+#endif		
-+    }
-+
-+    // misc irq
-+    if (status & 0x40) {
-+	irq_misc = cwain_inb(cwaintmp->span[0],cwain_R_IRQ_MISC);
-+	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], cwaintmp->ticks);
-+	    }
-+	    if (cwaintmp->ticks == (cwain_FRAME_SIZE / 8)) {
-+		cwaintmp->ticks = 0;
-+	    }
-+	} 
-+	if (irq_misc & 0x1) {
-+	    /* state machine */
-+	    if (debug > 4)
-+		printk(KERN_INFO "cwain: state machine irq\n");
-+	    l1event++;
-+	}
-+	if (irq_misc & 0x10) {
-+    	    if (l1event == 0) {
-+		/* just in case we missed it */
-+		for (i=0;i<cwaintmp->spans;i++) {
-+    	    	    l1event += cwain_isr_sync(cwaintmp->span[i]);
-+    		}
-+	    }
-+	}
-+    }
-+
-+    // misc irq
-+    if (status2 & 0x40) {
-+	if (cwaintmp->spans == 2) {
-+	    irq_misc2 = cwain_inb(cwaintmp->span[1],cwain_R_IRQ_MISC);
-+	}
-+	if (irq_misc2 & 0x1) {
-+	    /* state machine 2 */
-+	    if (debug > 4)
-+		printk(KERN_INFO "cwain: state machine 2 irq\n");
-+	    l1event++;
-+	}
-+    }
-+
-+    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);
-+        }
-+    }
-+
-+#ifdef RELAXED_LOCKING    
-+    spin_unlock(&(cwaintmp->lock));
-+#else
-+    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
-+#endif
-+#ifdef LINUX26
-+	return IRQ_RETVAL(1);
-+#endif		
-+}
-+
-+static int ztcwain_open(struct zt_chan *chan) {
-+//    printk(KERN_INFO "cwain: channel %d opened.\n",chan->channo);
-+#ifndef LINUX26
-+    MOD_INC_USE_COUNT;
-+#else
-+    try_module_get(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int ztcwain_close(struct zt_chan *chan) {
-+//    printk(KERN_INFO "cwain: channel %d closed.\n",chan->channo);
-+#ifndef LINUX26
-+    MOD_DEC_USE_COUNT;
-+#else
-+    module_put(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int ztcwain_rbsbits(struct zt_chan *chan, int bits) {
-+    return 0;
-+}
-+
-+static int ztcwain_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
-+        switch(cmd) {
-+        default:
-+                return -ENOTTY;
-+        }
-+        return 0;
-+}
-+
-+static int ztcwain_startup(struct zt_span *span) {
-+    struct zt_cwain_card *cwaincard = span->pvt;
-+    struct zt_cwain *cwaintmp;
-+    unsigned long flags;
-+    int alreadyrunning;
-+    int i=0;
-+
-+//    printk(KERN_INFO "cwain: startup spanno %d offset %d\n", span->spanno, span->offset);
-+
-+    if (cwaincard == NULL) {
-+	printk(KERN_CRIT "cwain: cwaincard == NULL!\n");
-+	return 0;
-+    }
-+
-+    cwaintmp = cwaincard->span[span->offset];
-+    if (cwaintmp == NULL) {
-+	printk(KERN_CRIT "cwain: cwaintmp == NULL!\n");
-+	return 0;
-+    }
-+
-+    
-+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-+//    printk(KERN_CRIT "already running %d flags %d\n", alreadyrunning, span->flags);
-+
-+    if (!alreadyrunning) {
-+	span->chans[15].flags &= ~ZT_FLAG_HDLC;
-+	span->chans[15].flags |= ZT_FLAG_BRIDCHAN; /* yes! */
-+    
-+	/* setup B channel buffers (8 bytes each) */
-+	for (i=0; i<15 ; i++) {
-+	    memset(cwaintmp->rxbuf[i],0x0,sizeof(cwaintmp->rxbuf[i]));
-+    	    memset(cwaintmp->txbuf[i],0x0,sizeof(cwaintmp->txbuf[i]));
-+
-+    	    span->chans[i].readchunk = cwaintmp->rxbuf[i];
-+	    span->chans[i].writechunk = cwaintmp->txbuf[i];
-+	}
-+	for (i=16; i<31 ; i++) {
-+	    memset(cwaintmp->rxbuf[i-1],0x0,sizeof(cwaintmp->rxbuf[i-1]));
-+    	    memset(cwaintmp->txbuf[i-1],0x0,sizeof(cwaintmp->txbuf[i-1]));
-+    	    span->chans[i].readchunk = cwaintmp->rxbuf[i-1];
-+	    span->chans[i].writechunk = cwaintmp->txbuf[i-1];
-+	}
-+	/* setup D channel buffer */
-+    	memset(cwaintmp->dtxbuf,0x0,sizeof(cwaintmp->dtxbuf));
-+	span->chans[15].writechunk = cwaintmp->dtxbuf;
-+	cwaintmp->chans[15].maxbytes2transmit = sizeof(cwaintmp->dtxbuf);
-+
-+	memset(cwaintmp->drxbuf,0x0,sizeof(cwaintmp->drxbuf));
-+    	span->chans[15].readchunk = cwaintmp->drxbuf;
-+
-+	span->flags |= ZT_FLAG_RUNNING;
-+    } else {
-+	printk(KERN_CRIT "already running\n");
-+	return 0;
-+    }
-+
-+    spin_lock_irqsave(&cwaintmp->lock,flags);
-+    // irqs off
-+    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
-+
-+    /* setup D-FIFO TX */
-+    cwain_outb(cwaintmp,cwain_R_FIFO,0x1F << 1);
-+    cwain_waitbusy(cwaintmp);
-+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+    cwain_waitbusy(cwaintmp);
-+    cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x1);
-+    cwain_outb(cwaintmp,cwain_A_SUBCH_CFG,0x0);
-+    cwain_outb(cwaintmp,cwain_A_CHANNEL,0x10 << 1);
-+    cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
-+
-+    /* setup D-FIFO RX */
-+    cwain_outb(cwaintmp,cwain_R_FIFO,(0x1F << 1) | 1);
-+    cwain_waitbusy(cwaintmp);
-+    cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+    cwain_waitbusy(cwaintmp);
-+    cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x1);
-+    cwain_outb(cwaintmp,cwain_A_SUBCH_CFG,0x0);
-+    cwain_outb(cwaintmp,cwain_A_CHANNEL,(0x10 << 1) | 1);
-+    cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
-+
-+    /* setup B-FIFOs TX */
-+    /* map ts 1 to 15 to fifos 0 to 14 */
-+    for (i=1; i<16 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,(i - 1) << 1);
-+	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+	cwain_waitbusy(cwaintmp);
-+	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
-+	cwain_outb(cwaintmp,cwain_A_CHANNEL,i << 1);
-+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
-+    }
-+    /* map ts 17 to 31 to fifos 15 to 29 */
-+    for (i=17; i<32 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,(i - 2) << 1);
-+	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+	cwain_waitbusy(cwaintmp);
-+	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
-+	cwain_outb(cwaintmp,cwain_A_CHANNEL,i << 1);
-+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
-+    }
-+
-+    /* setup B-FIFOs RX */
-+    /* map ts 1 to 15 to fifos 0 to 14 */
-+    for (i=1; i<16 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,((i-1) << 1) | 1);
-+    	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+    	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
-+    	cwain_outb(cwaintmp,cwain_A_CHANNEL,(i << 1) | 1);
-+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
-+    }
-+    /* map ts 17 to 31 to fifos 15 to 29 */
-+    for (i=17; i<32 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,((i-2) << 1) | 1);
-+    	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_R_INC_RES_FIFO,0x2);
-+    	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_A_CON_HDLC,0x2);
-+    	cwain_outb(cwaintmp,cwain_A_CHANNEL,(i << 1) | 1);
-+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x1);
-+    }
-+
-+    if (debug)
-+        printk(KERN_INFO "cwain: starting card %d span %d/%d.\n",cwaintmp->cardno,span->spanno,span->offset);
-+
-+    if (cwaincard->spans == 1) {
-+	cwain_set_master(cwaincard, 0);
-+    }
-+    
-+    /* setup E1 amplitude */
-+    cwain_outb(cwaintmp,cwain_R_PWM_MD,0x20);
-+    cwain_outb(cwaintmp,cwain_R_PWM0,0x50);
-+    cwain_outb(cwaintmp,cwain_R_PWM1,0xff);
-+
-+    /* setup E1 transceiver */
-+    cwain_outb(cwaintmp,cwain_R_TX_SL0,0xf8);  // R_TX_FR1
-+    cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG0,0x00); /* semiautomatic mode */
-+
-+    cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG0,0x6); /* 0x26 */
-+
-+    if (cwaintmp->span.lineconfig & ZT_CONFIG_AMI) {
-+	cwain_outb(cwaintmp,cwain_R_TX0,0x82);
-+	cwain_outb(cwaintmp,cwain_R_RX0,0x02);
-+    } else if (cwaintmp->span.lineconfig & ZT_CONFIG_HDB3) {
-+	cwain_outb(cwaintmp,cwain_R_TX0,0x81);
-+	cwain_outb(cwaintmp,cwain_R_RX0,0x01);
-+    }
-+
-+    /* transmitter mode */
-+    cwain_outb(cwaintmp,cwain_R_TX1,0x60); 
-+
-+    cwain_outb(cwaintmp,cwain_R_LOS0,0x10);
-+    cwain_outb(cwaintmp,cwain_R_LOS1,0x10);
-+
-+    if (cwaintmp->span.lineconfig & ZT_CONFIG_CRC4) {
-+	/* crc4 multiframe */
-+	cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG1,0x31);
-+//	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x41);
-+	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x03);
-+    } else {
-+	/* doubleframe */
-+	cwain_outb(cwaintmp,cwain_R_TX_SL0_CFG1,0x0);
-+//	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x40);
-+	cwain_outb(cwaintmp,cwain_R_RX_SL0_CFG1,0x02);
-+    }
-+
-+    
-+    /* setup sync mode */    
-+    if (cwaincard->syncs[span->offset] > 0) {
-+	cwain_outb(cwaintmp,cwain_R_SYNC_CTRL,0x2);
-+	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_OUT,0xe0);
-+	/* layer 1, up! */
-+	cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x11);
-+    }
-+    
-+    cwaintmp->sync = 0;
-+    cwaintmp->sync_sta = 0;
-+    
-+    /* enable irqs */
-+    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;
-+}
-+
-+static int ztcwain_shutdown(struct zt_span *span) {
-+    struct zt_cwain_card *cwaincard = span->pvt;
-+    struct zt_cwain *cwaintmp;
-+    unsigned long flags;
-+    int alreadyrunning;
-+    int i=0;
-+    
-+    if (cwaincard == NULL) {
-+	printk(KERN_CRIT "cwain: cwaincard == NULL!\n");
-+	return 0;
-+    }
-+
-+    cwaintmp = cwaincard->span[span->offset];
-+    if (cwaintmp == NULL) {
-+	printk(KERN_CRIT "cwain: cwaintmp == NULL!\n");
-+	return 0;
-+    }
-+
-+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-+    
-+    if (!alreadyrunning) {
-+	return 0;
-+    }
-+    spin_lock_irqsave(&cwaintmp->lock,flags);
-+
-+//    printk(KERN_CRIT "cwain: stopping card %d span %d/%d.\n",cwaintmp->cardno,span->spanno,span->offset);
-+
-+    // turn off irqs for all fifos
-+
-+    /* disable FIFO TX */
-+    for (i=0; i<0x20 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,i << 1);
-+	cwain_waitbusy(cwaintmp);
-+	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
-+    }
-+
-+    /* disable FIFO RX */
-+    for (i=0; i<0x20 ; i++) {
-+	cwain_outb(cwaintmp,cwain_R_FIFO,(i << 1) | 1);
-+    	cwain_waitbusy(cwaintmp);
-+    	cwain_outb(cwaintmp,cwain_A_IRQ_MSK,0x0);
-+    }
-+
-+
-+    /* Deactivate Layer 1 */
-+    cwain_outb(cwaintmp,cwain_R_E1_WR_STA,0x10);
-+
-+    cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
-+//    cwain_outb(cwaintmp,cwain_R_IRQMSK_MISC, 0); 
-+    cwain_inb(cwaintmp,cwain_R_STATUS);
-+
-+
-+    span->flags &= ~ZT_FLAG_RUNNING;
-+
-+
-+    spin_unlock_irqrestore(&cwaintmp->lock,flags);
-+
-+//    printk(KERN_CRIT "cwain: card %d span %d/%d down.\n",cwaintmp->cardno,span->spanno,span->offset);
-+    return 0;
-+}
-+
-+static int ztcwain_maint(struct zt_span *span, int cmd) {
-+    return 0;
-+}
-+
-+static int ztcwain_chanconfig(struct zt_chan *chan,int sigtype) {
-+//    printk(KERN_INFO "chan_config sigtype=%d\n", sigtype);
-+    return 0;
-+}
-+
-+static int ztcwain_spanconfig(struct zt_span *span,struct zt_lineconfig *lc) {
-+    struct zt_cwain_card *cwaincard = span->pvt;
-+    span->lineconfig = lc->lineconfig;
-+    span->syncsrc = lc->sync;
-+
-+    cwaincard->syncs[span->offset] = lc->sync;
-+    cwaincard->syncsrc = -1;
-+//    printk(KERN_INFO "span_config %d lineconfig=%d syncsrc=%d\n", span->spanno, lc->lineconfig, lc->sync);
-+//    cwain_check_timing(cwaincard);
-+    return 0;
-+}
-+
-+static int ztcwain_initialize(struct zt_cwain *cwaintmp, struct zt_cwain_card *cwaincard, int offset) {
-+    int i=0;
-+    
-+	memset(&cwaintmp->span,0,sizeof(struct zt_span)); // you never can tell...
-+	sprintf(cwaintmp->span.name,"cwain/%d",cwaintmp->cardno);
-+	switch (cwaintmp->type) {
-+	    case 0xb553:
-+		sprintf(cwaintmp->span.desc,"Junghanns.NET singleE1 PCI ISDN Card %d (cardID %d)",cwaintmp->cardno,cwaintmp->cardID);
-+		break;
-+	    case 0xb554:
-+		sprintf(cwaintmp->span.desc,"Junghanns.NET doubleE1 PCI ISDN Card %d (cardID %d) (1 E1 port)",cwaintmp->cardno,cwaintmp->cardID);
-+		break;
-+	    default:
-+		return -1;
-+	}
-+        cwaintmp->span.spanconfig = ztcwain_spanconfig;
-+        cwaintmp->span.chanconfig = ztcwain_chanconfig;
-+        cwaintmp->span.startup = ztcwain_startup;
-+        cwaintmp->span.shutdown = ztcwain_shutdown;
-+        cwaintmp->span.maint = ztcwain_maint;
-+        cwaintmp->span.rbsbits = ztcwain_rbsbits;
-+        cwaintmp->span.open = ztcwain_open;
-+        cwaintmp->span.close = ztcwain_close;
-+        cwaintmp->span.ioctl = ztcwain_ioctl;
-+
-+        cwaintmp->span.chans = cwaintmp->chans;
-+        cwaintmp->span.channels = 31;
-+        cwaintmp->span.deflaw = ZT_LAW_ALAW;
-+        cwaintmp->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_HDB3 | ZT_CONFIG_CCS; 
-+        init_waitqueue_head(&cwaintmp->span.maintq);
-+        cwaintmp->span.pvt = cwaincard;
-+        cwaintmp->span.offset = offset;
-+
-+	for (i=0; i < cwaintmp->span.channels; i++) {
-+	    memset(&(cwaintmp->chans[i]),0x0,sizeof(struct zt_chan));
-+	    sprintf(cwaintmp->chans[i].name,"cwain%d/%d",cwain_span_count + 1,i + 1);
-+	    cwaintmp->chans[i].pvt = cwaintmp;
-+	    cwaintmp->chans[i].sigcap =  ZT_SIG_CLEAR;
-+	    cwaintmp->chans[i].chanpos = i + 1; 
-+	}
-+
-+	if (zt_register(&cwaintmp->span,0)) {
-+	    printk(KERN_INFO "cwain: unable to register zaptel span!\n");
-+	    return -1;
-+	}
-+//	 printk(KERN_INFO "cwain: registered zaptel span %d.\n",s+1);
-+
-+    return 0;
-+}
-+
-+int cwain_reset_card(struct zt_cwain_card *cwaintmp) {
-+    unsigned long flags;
-+    int i = 0;
-+
-+    cwaintmp->irq = cwaintmp->span[0]->irq;
-+    
-+    if (cwaintmp->spans == 2) {
-+	if (request_irq(cwaintmp->irq, cwain_interrupt, SA_INTERRUPT | SA_SHIRQ, "cwain2", cwaintmp)) {
-+    	    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");
-+	    return -1;
-+	}
-+    }
-+
-+    spin_lock_irqsave(&(cwaintmp->lock),flags);
-+
-+    for (i=0;i<cwaintmp->spans;i++) {
-+	cwain_reset_span(cwaintmp->span[i]);
-+    }
-+
-+    /* no master yet, force reelection */
-+    cwaintmp->syncsrc = -1;
-+    
-+    /* set up the timer 1 khz, zaptel timing */
-+    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, 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); 
-+
-+    spin_unlock_irqrestore(&(cwaintmp->lock),flags);
-+    return 0;
-+}
-+
-+int cwain_find_spans(unsigned int pcidid) {
-+    struct pci_dev *tmp;
-+    struct zt_cwain *cwaintmp = NULL;
-+    int i=0;
-+    unsigned char dips=0;
-+    int cid=0;
-+    int modes=0;
-+    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_cwain);
-+    while (tmp != NULL) {
-+	multi_cwain = tmp;	// skip this next time.
-+
-+	if (pci_enable_device(tmp)) {
-+	    multi_cwain = NULL;
-+	    return -1;
-+	}
-+
-+	cwaintmp = kmalloc(sizeof(struct zt_cwain),GFP_KERNEL);
-+	if (!cwaintmp) {
-+	    printk(KERN_WARNING "cwain: unable to kmalloc!\n");
-+	    pci_disable_device(tmp);
-+	    multi_cwain = NULL;
-+	    return -ENOMEM;
-+	}
-+	memset(cwaintmp, 0x0, sizeof(struct zt_cwain));
-+	
-+	spin_lock_init(&cwaintmp->lock);
-+	cwaintmp->pcidev = tmp;
-+	cwaintmp->pcibus = tmp->bus->number;
-+	cwaintmp->pcidevfn = tmp->devfn; 
-+
-+
-+	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;
-+	    return -EIO;
-+	}
-+
-+	if (!tmp->irq) {
-+	    printk(KERN_WARNING "cwain: PCI device has no irq!\n");
-+	    pci_disable_device(tmp);
-+	    multi_cwain = NULL;
-+	    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_phys, 256);
-+			       
-+	/* enable memio */
-+	pci_write_config_word(cwaintmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_IO);	
-+
-+	/* disable interrupts */
-+	cwain_outb(cwaintmp,cwain_R_IRQ_CTRL, 0); 
-+
-+        if (((tmp->subsystem_device==0xb553) || (tmp->subsystem_device==0xb554))&& (pcidid == PCI_DEVICE_ID_CCD_E)) {
-+	    dips = (cwain_inb(cwaintmp,cwain_R_GPI_IN0) >> 5);
-+	    cid = 7;
-+	    for (i=0;i<3;i++) {
-+	        if ((dips & (1 << i)) != 0) {
-+	    	cid -= (1 << (2-i));
-+	        }
-+	    }
-+//		printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
-+        } else {
-+	    cid = 0xff;
-+        }
-+
-+	if (ports == -1) {
-+    	    if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_E)) {
-+		modes = (cwain_inb(cwaintmp,cwain_R_GPI_IN0) >> 4) & 0x01;
-+	    } else {
-+		modes = 0; // assume TE mode
-+	    }
-+	} else {
-+	    modes = ports >> cwain_span_count;
-+	}
-+
-+
-+	cwaintmp->cardID = cid;
-+	cwaintmp->type = tmp->subsystem_device;
-+
-+	if ((modes & 1) != 0) {
-+	    cwaintmp->nt_mode = 1;
-+	} else {
-+	    cwaintmp->nt_mode = 0;
-+	}
-+
-+	cwain_register_span(cwaintmp);
-+
-+	tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_cwain);
-+    }
-+    return 0;
-+}
-+
-+
-+int cwain_sort_cards(void) {
-+    int changed=0,tmpcardno;
-+    struct zt_cwain_card *tmpcard,*tmpcard2;
-+    spin_lock(&cwain_card_registerlock);
-+    do {
-+	changed = 0;
-+	tmpcard = cwain_card_list;
-+	while (tmpcard != NULL) {
-+	    if (tmpcard->prev) {
-+		if (tmpcard->prev->cardID > tmpcard->cardID) {
-+		    tmpcardno = tmpcard->prev->cardno;
-+		    tmpcard->prev->cardno = tmpcard->cardno; 
-+		    tmpcard->cardno = tmpcardno;
-+		
-+		    tmpcard2 = tmpcard->prev;
-+		    if (tmpcard2->prev) {
-+			tmpcard2->prev->next = tmpcard;
-+		    } else {
-+			cwain_card_list = tmpcard;
-+		    }
-+		    if (tmpcard->next) {
-+			tmpcard->next->prev = tmpcard2;
-+		    } 
-+		    tmpcard2->next = tmpcard->next;
-+		    tmpcard->prev = tmpcard2->prev;
-+		    tmpcard->next = tmpcard2;
-+		    tmpcard2->prev = tmpcard;
-+		    changed = 1;
-+		    tmpcard = tmpcard2;
-+		}
-+	    }
-+	    tmpcard = tmpcard->next;
-+	}
-+    } while (changed == 1);
-+    spin_unlock(&cwain_card_registerlock);
-+    return 0;
-+}
-+
-+int cwain_zap_cards(void) {
-+    struct zt_cwain_card *tmpcard = cwain_card_list;
-+    int i=0;
-+    int res=0;
-+    while (tmpcard != NULL) {
-+	for (i=0; i<tmpcard->spans; i++) {
-+	    ztcwain_initialize(tmpcard->span[i], tmpcard, i);
-+	}
-+	res = cwain_reset_card(tmpcard);
-+	tmpcard = tmpcard->next;
-+    }
-+    return res;
-+}
-+
-+
-+int init_module(void) {
-+    multi_cwain = NULL;
-+    cwain_find_spans(PCI_DEVICE_ID_CCD_E);
-+    cwain_sort_cards();
-+    cwain_zap_cards();
-+    if (cwain_card_count == 0) {
-+	printk(KERN_INFO "cwain: no cwain cards found.\n");
-+    } else {
-+	printk(KERN_INFO "cwain: %d cwain card(s) in this box, %d E1 ports total.\n", cwain_card_count, cwain_span_count);
-+    }
-+    return 0;
-+}
-+
-+void cleanup_module(void) {
-+    struct zt_cwain_card *tmpcard,*tmplist;
-+    struct zt_cwain *tmpspan,*spanlist;
-+    int i=0;
-+    int j=0;
-+    
-+    tmplist = cwain_card_list;
-+    tmpcard = NULL;
-+    while (tmplist) {
-+	tmpcard = tmplist;
-+	tmplist = tmplist->next;
-+
-+	tmpcard->dead = 1;
-+	cwain_shutdown_card(tmpcard);
-+	kfree(tmpcard);
-+	i++;
-+    }
-+
-+    spanlist = cwain_span_list;
-+    tmpspan = NULL;
-+    while (spanlist) {
-+	tmpspan = spanlist;
-+	spanlist = spanlist->next;
-+	kfree(tmpspan);
-+	j++;
-+    }
-+    printk(KERN_INFO "cwain: shutdown %d spans, %d cwain cards.\n", j, i);
-+}
-+#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.6/cwain/cwain.h /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/cwain.h
---- zaptel-1.2.6/cwain/cwain.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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_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;
-+    unsigned int type;
-+
-+    /* lock to protect the structure */
-+    spinlock_t lock;
-+    int cardID;
-+    unsigned char cardno;
-+    
-+    /* ticks and clicks, fish and chips */
-+    unsigned int ticks;
-+    unsigned int clicks;
-+    unsigned char nt_mode;
-+    unsigned char sync_sta;
-+    unsigned char sync;
-+    int syncmode;
-+    
-+    /* blinky blink */
-+    unsigned char leds[4];
-+
-+    /* 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;
-+    /* D chan buffer */
-+    unsigned char drxbuf[cwain_DFIFO_SIZE];
-+    unsigned char dtxbuf[cwain_DFIFO_SIZE];
-+
-+
-+    /* zaptel resources */
-+    struct zt_span span;
-+    struct zt_chan chans[31];
-+
-+    /* more zaptel stuff */
-+    unsigned int usecount;
-+    int spantype;
-+    int spanflags;
-+
-+    /* linked list */
-+    struct zt_cwain *next;
-+    struct zt_cwain *prev;
-+
-+} zt_cwain;
-+
-+typedef struct zt_cwain_card {
-+    /* lock to protect the structure */
-+    spinlock_t lock;
-+
-+    unsigned int spans;
-+    unsigned int dead;
-+    int cardID;
-+    unsigned char cardno;
-+    unsigned int ticks;
-+
-+    struct zt_cwain *span[2];
-+    int syncsrc;
-+    int syncs[2];
-+    int master[2];
-+    
-+    unsigned int irq;   
-+    unsigned int pcibus;
-+
-+    /* linked list */
-+    struct zt_cwain_card *next;
-+    struct zt_cwain_card *prev;
-+} zt_cwain_card;
-+
-+#define cwain_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
-+#define cwain_inb(a,b) (readb((a)->pci_io+(b)))
-+
-+#define cwain_outw(a,b,c) (writew((c),(a)->pci_io+(b)))
-+#define cwain_inw(a,b) (readw((a)->pci_io+(b)))
-+
-+#define cwain_outdw(a,b,c) (writel((c),(a)->pci_io+(b)))
-+#define cwain_indw(a,b) (readl((a)->pci_io+(b)))
-+
-+
-+/* Write only registers */
-+#define cwain_A_CH_MSK		0xF4
-+#define cwain_A_CHANNEL 	0xFC
-+#define cwain_A_CON_HDLC	0xFA
-+#define cwain_A_CONF		0xD1
-+#define cwain_A_FIFO_SEQ	0xFD
-+#define cwain_R_INC_RES_FIFO	0x0E
-+#define cwain_A_IRQ_MSK		0xFF
-+#define cwain_A_SL_CFG		0xD0
-+#define cwain_A_SUBCH_CFG	0xFB
-+#define cwain_R_BERT_WD_MD	0x1B
-+#define cwain_R_BRG_PCM_CFG	0x02
-+#define cwain_R_CIRM		0x00
-+#define cwain_R_CONF_EN		0x18
-+#define cwain_R_CTRL		0x01
-+#define cwain_R_DTMF		0x1C
-+#define cwain_R_DTMF_N		0x1D
-+#define cwain_R_E1_WR_STA	0x20
-+#define cwain_R_FIFO_MD		0x0D
-+#define cwain_R_FIFO		0x0F
-+#define cwain_R_FIRST_FIFO	0x0B
-+#define cwain_R_FSM_IDX		0x0F
-+#define cwain_R_GPIO_EN0	0x42
-+#define cwain_R_GPIO_EN1	0x43
-+#define cwain_R_GPIO_OUT0	0x40
-+#define cwain_R_GPIO_OUT1	0x41
-+#define cwain_R_GPIO_SEL	0x44
-+#define cwain_R_IRQ_CTRL	0x13
-+#define cwain_R_IRQMSK_MISC	0x11
-+#define cwain_R_JATT_CFG	0x2F
-+#define cwain_R_LOS0		0x22
-+#define cwain_R_LOS1		0x23
-+#define cwain_R_PCM_MD0		0x14
-+#define cwain_R_PCM_MD1		0x15
-+#define cwain_R_PCM_MD2		0x15
-+#define cwain_R_PWM_MD		0x46
-+#define cwain_R_PWM0		0x38
-+#define cwain_R_PWM1		0x39
-+#define cwain_R_RAM_ADDR0	0x08
-+#define cwain_R_RAM_ADDR1	0x09
-+#define cwain_R_RAM_ADDR2	0x0A
-+#define cwain_R_RAM_MISC	0x0C
-+#define cwain_R_RX_OFFS		0x30
-+#define cwain_R_RX_SL0_CFG0	0x25
-+#define cwain_R_RX_SL0_CFG1	0x26
-+#define cwain_R_RX0		0x24
-+#define cwain_R_SH0H		0x15
-+#define cwain_R_SH0L		0x15
-+#define cwain_R_SH1H		0x15
-+#define cwain_R_SH1L		0x15
-+#define cwain_R_SL_SEL0		0x15
-+#define cwain_R_SL_SEL1		0x15
-+#define cwain_R_SL_SEL2		0x15
-+#define cwain_R_SL_SEL3		0x15
-+#define cwain_R_SL_SEL4		0x15
-+#define cwain_R_SL_SEL5		0x15
-+#define cwain_R_SL_SEL6		0x15
-+#define cwain_R_SL_SEL7		0x15
-+#define cwain_R_SLOT		0x10
-+#define cwain_R_SYNC_CTRL	0x35
-+#define cwain_R_SYNC_OUT	0x31
-+#define cwain_R_TI_WD		0x1A
-+#define cwain_R_TX_OFFS		0x34
-+#define cwain_R_TX_SL0_CFG0	0x2C
-+#define cwain_R_TX_SL0_CFG1	0x2E
-+#define cwain_R_TX_SL0		0x2D
-+#define cwain_R_TX0		0x28
-+#define cwain_R_TX1		0x29
-+
-+#define cwain_R_TX_FR0		0x2C
-+#define cwain_R_TX_FR1		0x2D
-+#define cwain_R_TX_FR2		0x2E
-+
-+#define cwain_R_RX_FR0		0x25
-+#define cwain_R_RX_FR1		0x26
-+
-+/* Read only registers */
-+#define cwain_A_F1		0x0C
-+#define cwain_A_F12		0x0C
-+#define cwain_A_F2		0x0D
-+#define cwain_A_Z1		0x04
-+#define cwain_A_Z12		0x04
-+#define cwain_A_Z1H		0x05
-+#define cwain_A_Z1L		0x04
-+#define cwain_A_Z2		0x06
-+#define cwain_A_Z2H		0x07
-+#define cwain_A_Z2L		0x06
-+#define cwain_R_BERT_ECH	0x1B
-+#define cwain_R_BERT_ECL	0x1A
-+#define cwain_R_BERT_STA	0x17
-+#define cwain_R_CHIP_ID		0x16
-+#define cwain_R_CHIP_RV		0x1F
-+#define cwain_R_CONF_OFLOW	0x14
-+#define cwain_R_CRC_ECH		0x35
-+#define cwain_R_CRC_ECL		0x34
-+#define cwain_R_E_ECH		0x37
-+#define cwain_R_E_ECL		0x36
-+#define cwain_R_E1_RD_STA	0x20
-+#define cwain_R_F0_CNTH		0x19
-+#define cwain_R_F0_CNTL		0x18
-+#define cwain_R_FAS_ECH		0x31
-+#define cwain_R_FAS_ECL		0x30
-+#define cwain_R_GPI_IN0		0x44
-+#define cwain_R_GPI_IN1		0x45
-+#define cwain_R_GPI_IN2		0x46
-+#define cwain_R_GPI_IN3		0x47
-+#define cwain_R_GPIO_IN0	0x40
-+#define cwain_R_GPIO_IN1	0x41
-+#define cwain_R_INT_DATA	0x88
-+#define cwain_R_IRQ_FIFO_BL0	0xC8
-+#define cwain_R_IRQ_FIFO_BL1	0xC9
-+#define cwain_R_IRQ_FIFO_BL2	0xCA
-+#define cwain_R_IRQ_FIFO_BL3	0xCB
-+#define cwain_R_IRQ_FIFO_BL4	0xCC
-+#define cwain_R_IRQ_FIFO_BL5	0xCD
-+#define cwain_R_IRQ_FIFO_BL6	0xCE
-+#define cwain_R_IRQ_FIFO_BL7	0xCF
-+#define cwain_R_IRQ_MISC	0x11
-+#define cwain_R_IRQ_OVIEW	0x10
-+#define cwain_R_JATT_STA	0x2B
-+#define cwain_R_RAM_USE		0x15
-+#define cwain_R_RX_SL0_0	0x25
-+#define cwain_R_RX_SL0_1	0x26
-+#define cwain_R_RX_SL0_2	0x27
-+#define cwain_R_SA6_VAL13_ECH	0x39
-+#define cwain_R_SA6_VAL13_ECL	0x38
-+#define cwain_R_SA6_VAL23_ECH	0x3B
-+#define cwain_R_SA6_VAL23_ECL	0x3A
-+#define cwain_R_SLIP		0x2C
-+#define cwain_R_STATUS		0x1C
-+#define cwain_R_SYNC_STA	0x24
-+#define cwain_R_VIO_ECH		0x33
-+#define cwain_R_VIO_ECL		0x32
-+
-+
-+/* Read/Write registers */
-+#define cwain_A_FIFO_DATA0_NOINC	0x84
-+#define cwain_A_FIFO_DATA0	0x80
-+#define cwain_A_FIFO_DATA1_NOINC	0x84
-+#define cwain_A_FIFO_DATA1	0x80
-+#define cwain_A_FIFO_DATA2_NOINC	0x84
-+#define cwain_A_FIFO_DATA2	0x80
-+#define cwain_R_RAM_DATA	0xC0
-+
-+#define PCI_DEVICE_ID_CCD_E	0x30b1
-+
-+#define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
-+#define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
-+
-diff -urNad zaptel-1.2.6/cwain/LICENSE /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/LICENSE
---- zaptel-1.2.6/cwain/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/LICENSE	2005-09-26 09:59:05.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.6/cwain/Makefile /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/Makefile
---- zaptel-1.2.6/cwain/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
-+
-+HOSTCC=gcc
-+
-+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 -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)
-+
-+OBJS=cwain.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=cwain
-+
-+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)
-+
-+cwain.o: cwain.c cwain.h 
-+	$(CC) -c cwain.c $(KFLAGS)
-+
-+clean:	
-+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
-+	
-+testlinux24: all
-+	modprobe zaptel
-+	insmod ./cwain.o
-+	ztcfg -v
-+	cat /proc/interrupts
-+	sleep 1
-+	cat /proc/interrupts
-+	rmmod cwain zaptel
-+
-+testlinux26: all
-+	modprobe zaptel
-+	insmod ./cwain.ko
-+	ztcfg -v
-+	cat /proc/interrupts
-+	sleep 5
-+	cat /proc/interrupts
-+	rmmod cwain zaptel
-+
-+reload:	unload load
-+load:	load$(BUILDVER)
-+
-+test:	test$(BUILDVER)
-+
-+
-+loadlinux24: linux24
-+	modprobe zaptel
-+	insmod ./cwain.o
-+	ztcfg -v
-+
-+loadlinux26: linux26
-+	sync
-+	modprobe zaptel
-+	insmod ./cwain.ko debug=1
-+	ztcfg -v
-+
-+install:	install$(BUILDVER)
-+
-+installlinux26:
-+	install -D -m 644 cwain.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/cwain.ko
-+
-+installlinux24:
-+	install -D -m 644 cwain.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/cwain.o
-+
-+unload: 
-+	rmmod cwain zaptel
-diff -urNad zaptel-1.2.6/cwain/TODO /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/TODO
---- zaptel-1.2.6/cwain/TODO	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/TODO	2005-09-26 09:59:05.000000000 +0300
-@@ -0,0 +1 @@
-+
-diff -urNad zaptel-1.2.6/cwain/zapata.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/zapata.conf
---- zaptel-1.2.6/cwain/zapata.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/cwain/zapata.conf.doubleE1 /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/zapata.conf.doubleE1
---- zaptel-1.2.6/cwain/zapata.conf.doubleE1	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/cwain/zaptel.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/zaptel.conf
---- zaptel-1.2.6/cwain/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/zaptel.conf	2005-10-27 11:26:41.000000000 +0200
-@@ -0,0 +1,11 @@
-+loadzone=nl
-+defaultzone=nl
-+span=1,2,3,ccs,hdb3,crc4
-+
-+alaw=1-31
-+
-+bchan=1-15
-+dchan=16
-+bchan=17-31
-+
-+
-diff -urNad zaptel-1.2.6/cwain/zaptel.conf.doubleE1 /tmp/dpep.KTFxyR/zaptel-1.2.6/cwain/zaptel.conf.doubleE1
---- zaptel-1.2.6/cwain/zaptel.conf.doubleE1	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/qozap/LICENSE /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/LICENSE
---- zaptel-1.2.6/qozap/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/LICENSE	2006-02-22 20:41:09.000000000 +0200
-@@ -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.6/qozap/Makefile /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/Makefile
---- zaptel-1.2.6/qozap/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
-+
-+HOSTCC=gcc
-+
-+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 -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)
-+
-+OBJS=qozap.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=qozap
-+
-+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)
-+
-+qozap.o: qozap.c qozap.h 
-+	$(CC) -c qozap.c $(KFLAGS)
-+
-+clean:	
-+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
-+	rm -rf .tmp_versions
-+
-+testlinux24: all
-+	modprobe zaptel
-+	insmod ./qozap.o
-+	ztcfg -v
-+	cat /proc/interrupts
-+	sleep 1
-+	cat /proc/interrupts
-+	rmmod qozap zaptel
-+
-+testlinux26: all
-+	modprobe zaptel
-+	insmod ./qozap.ko
-+	ztcfg -v
-+	cat /proc/interrupts
-+	sleep 1
-+	cat /proc/interrupts
-+	rmmod qozap zaptel
-+
-+reload:	unload load
-+load:	load$(BUILDVER)
-+
-+test:	test$(BUILDVER)
-+
-+
-+loadlinux24: linux24
-+	modprobe zaptel
-+	insmod ./qozap.o
-+	ztcfg -v
-+
-+loadlinux26: linux26
-+	sync
-+	modprobe zaptel
-+	insmod ./qozap.ko
-+	ztcfg -v
-+
-+unload: 
-+	rmmod qozap zaptel
-+
-+install:	install$(BUILDVER)
-+
-+installlinux26:
-+	install -D -m 644 qozap.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/qozap.ko
-+
-+installlinux24:
-+	install -D -m 644 qozap.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/qozap.o
-diff -urNad zaptel-1.2.6/qozap/qozap.c /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/qozap.c
---- zaptel-1.2.6/qozap/qozap.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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!
-+ *
-+ * Copyright (C) 2003, 2004, 2005 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 "qozap.h"
-+
-+#if CONFIG_PCI
-+
-+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;
-+static int qoz_dev_count = 0;
-+static int totalBRIs = 0;
-+static struct pci_dev *multi_qoz = NULL;
-+static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
-+
-+static int ztqoz_shutdown(struct zt_span *span);
-+
-+int qoz_waitbusy(struct qoz_card *qoztmp) {
-+    int x=1000;
-+    while (x-- && (qoz_inb(qoztmp,qoz_R_STATUS) & 1));
-+    if (x < 0) {
-+	return -1;
-+    } else {
-+	return 0;
-+    }
-+}
-+
-+void qoz_shutdownCard(struct qoz_card *qoztmp) {
-+    int s=0;
-+    unsigned long flags;
-+    int stports=0;
-+    if (qoztmp == NULL) {
-+	printk(KERN_INFO "qozap: shutting down NULL card!\n");
-+	return;
-+    }
-+
-+    if ((qoztmp->pci_io == NULL) || (qoztmp->ioport == 0)) {
-+	return;
-+    }
-+
-+    if (debug)
-+	printk(KERN_INFO "qozap: shutting down card %d (cardID %d) at io port %#x.\n",qoztmp->cardno,qoztmp->cardID,(u_int) qoztmp->ioport);
-+
-+    if (qoztmp->ztdev != NULL) {
-+	stports = qoztmp->stports;
-+	for (s=0; s < stports; s++) {
-+	    if(qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
-+		ztqoz_shutdown(&qoztmp->ztdev->spans[s]);
-+		if (debug)
-+		    printk(KERN_INFO "qozap: shutdown card %d span %d.\n",qoztmp->cardno,s+1);
-+	    }
-+	}
-+    }
-+
-+    spin_lock_irqsave(&qoztmp->lock,flags);
-+
-+    // turn off irqs
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
-+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0); 
-+    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
-+
-+
-+    // softreset
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x8);
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
-+    qoz_waitbusy(qoztmp);
-+
-+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0); 
-+    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
-+
-+    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;
-+
-+    if (qoztmp->pcidev != NULL) {
-+        pci_disable_device(qoztmp->pcidev);
-+    }
-+    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, 0);	
-+    
-+    free_irq(qoztmp->irq,qoztmp);
-+    spin_unlock_irqrestore(&qoztmp->lock,flags);
-+
-+    if (qoztmp->ztdev != NULL) {
-+	stports = qoztmp->stports;
-+	for (s=0; s < stports; s++) {
-+	    if(qoztmp->ztdev->spans[s].flags & ZT_FLAG_REGISTERED) {
-+		zt_unregister(&qoztmp->ztdev->spans[s]);
-+		if (debug)
-+		    printk(KERN_INFO "qozap: unregistered card %d span %d.\n",qoztmp->cardno,s+1);
-+	    }
-+	}
-+	kfree(qoztmp->ztdev);
-+	qoztmp->ztdev = NULL;
-+    }
-+}
-+
-+void qoz_doLEDs(struct qoz_card *qoztmp) {
-+    unsigned char leds = 0x0;
-+    if ((qoztmp->type == 0xb520) && (qoztmp->stports == 4)){
-+//	if ((qoztmp->ticks > 0) && (qoztmp->ticks <= 300)) {
-+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x20 | 0x10);
-+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0xf);
-+	    qoz_outb(qoztmp,qoz_R_GPIO_OUT1,(qoztmp->leds[0] | (qoztmp->leds[1] << 1) | (qoztmp->leds[2] << 2) | (qoztmp->leds[3] << 3)));
-+/*	}
-+	if ((qoztmp->ticks > 300) && (qoztmp->ticks <= 600)) {
-+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0x0);
-+	} */
-+    } else if ((qoztmp->type == 0xb550) && (qoztmp->stports == 4)){
-+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x80 | 0x40 | 0x20 | 0x10);
-+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0xff);
-+	    if (qoztmp->leds[0] == 0) {
-+		leds |= 0x80;
-+	    } else {
-+		leds |= 0x40;
-+	    }
-+	    if (qoztmp->leds[1] == 0) {
-+		leds |= 0x10;
-+	    } else {
-+		leds |= 0x20;
-+	    }
-+	    if (qoztmp->leds[2] == 0) {
-+		leds |= 0x04;
-+	    } else {
-+		leds |= 0x08;
-+	    }
-+	    if (qoztmp->leds[3] == 0) {
-+		leds |= 0x02;
-+	    } else {
-+		leds |= 0x01;
-+	    }
-+    /* 	0x80 st1g
-+	0x40 st1r
-+	0x20 st2r
-+	0x10 st2g	
-+	0x08 st3r
-+	0x04 st3g
-+	0x02 st4g
-+	0x01 st4r
-+    */
-+	    qoz_outb(qoztmp,qoz_R_GPIO_OUT1, leds);
-+    }
-+}
-+
-+void qoz_doWD(struct qoz_card *qoztmp) {
-+    if (!qoztmp->wdp) {
-+	return;
-+    }
-+    if (qoztmp->wdp == 1) {
-+	    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P2);
-+	    qoztmp->wdp = 2;
-+    } else {
-+	    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P1);
-+	    qoztmp->wdp = 1;
-+    }
-+    qoz_inb_io(qoztmp,qoz_R_CHIP_ID);    
-+}
-+
-+void qoz_undoWD(struct qoz_card *qoztmp) {
-+    printk(KERN_INFO "qozap: Stopping hardware watchdog.\n");
-+    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P0);
-+    qoztmp->wdp = 0;
-+    qoz_inb_io(qoztmp,qoz_R_CHIP_ID);    
-+}
-+
-+void qoz_resetCard(struct qoz_card *qoztmp) {
-+    unsigned long flags;
-+    unsigned char i=0;
-+    spin_lock_irqsave(&(qoztmp->lock),flags);
-+    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-+    
-+    // soft reset
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x8);
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
-+    qoz_waitbusy(qoztmp);
-+
-+    // fifo reset
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x10);
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
-+    qoz_waitbusy(qoztmp);
-+
-+    // s/t reset
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x40);
-+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
-+    qoz_waitbusy(qoztmp);
-+
-+    /* set S0 amplitude */
-+    qoz_outb(qoztmp,qoz_R_PWM_MD,0xa0);
-+    if (qoztmp->type == 0xb552) {
-+	qoz_outb(qoztmp,qoz_R_PWM0,0x19);
-+    } else {
-+	qoz_outb(qoztmp,qoz_R_PWM0,0x1E);
-+    }
-+
-+    /* set up the timer */
-+    qoz_outb(qoztmp,qoz_R_TI_WD, 0x2); 
-+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0x2); 
-+
-+    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); 
-+
-+    if (qoztmp->type == 0xb552) {
-+        qoz_outb(qoztmp,qoz_R_FIFO_MD,0x16);
-+    } else {
-+        qoz_outb(qoztmp,qoz_R_FIFO_MD,0x26);
-+    }
-+
-+    // double clock
-+    if (doubleclock == 1) {
-+	// hopefully you have set CLK_MODE correctly!
-+	qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
-+    } else {
-+	if (qoztmp->type == 0x08b4) {
-+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x0); 
-+	} else if (qoztmp->type == 0xb550) {
-+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x23); 
-+	} else if (qoztmp->type == 0xb520) {
-+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
-+	} else {
-+	    /* you are on your own here! */
-+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
-+	}
-+    }
-+    qoz_outb(qoztmp,qoz_R_CTRL,0x0); 
-+
-+    /* R0 G1 */
-+    qoztmp->leds[0] = 0x0;
-+    qoztmp->leds[1] = 0x0;
-+    qoztmp->leds[2] = 0x0;
-+    qoztmp->leds[3] = 0x0;
-+    qoztmp->leds[4] = 0x0;
-+    qoztmp->leds[5] = 0x0;
-+    qoztmp->leds[6] = 0x0;
-+    qoztmp->leds[7] = 0x0;
-+
-+    /* Finally enable IRQ output */
-+//    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0x8 | 0x1); 
-+    if (qoztmp->type == 0xb552) {
-+	qoztmp->stports = 8;
-+    } else {
-+	qoztmp->stports = 4;
-+    }
-+    qoztmp->ticks = 0;
-+    qoztmp->clicks = 0;
-+    if (qoztmp->type == 0xb550) {
-+	printk(KERN_INFO "qozap: Starting hardware watchdog.\n");
-+	qoztmp->wdp = 2;
-+    } else {
-+	qoztmp->wdp = 0;
-+    }
-+
-+    for (i=0;i<qoztmp->stports;i++) {
-+	if (qoztmp->st[i].nt_mode) {
-+	    qoz_outb(qoztmp,qoz_R_ST_SYNC,0x8 | i);
-+	    if (debug)
-+		printk(KERN_INFO "qoztmp: using NT port %d for sync\n", i);
-+	    break;
-+	}
-+    }
-+    if (i == qoztmp->stports) {
-+	qoz_outb(qoztmp,qoz_R_ST_SYNC,0x0);
-+    }
-+    spin_unlock_irqrestore(&(qoztmp->lock),flags);
-+}
-+
-+void qoz_registerCard(struct qoz_card *qozcard) {
-+    spin_lock(&registerlock);
-+    if (qozcard != NULL) {
-+	qozcard->prev = NULL;
-+	qozcard->next = qoz_dev_list;
-+	if (qoz_dev_list) {
-+	    qoz_dev_list->prev = qozcard;
-+	}
-+	qoz_dev_list = qozcard;
-+	qozcard->cardno = ++qoz_dev_count;
-+    } else {
-+	printk(KERN_INFO "qozap: trying to register NULL card.\n");
-+    }
-+    spin_unlock(&registerlock);
-+}
-+
-+static int qoz_dfifo_tx(struct qoz_card *qoztmp, int stport) {
-+    int chan = 2;
-+    int x=0;
-+    char fifo = 0;
-+    char offset = 0;
-+
-+    if (qoztmp->type == 0xb552) {
-+	offset = 24;
-+    } else {
-+	offset = 28;
-+    }
-+
-+    fifo = stport + offset;
-+
-+    if (qoztmp->ztdev->chans[stport][chan].bytes2transmit < 1) {
-+	return 0;
-+    } else {
-+	/* select fifo */
-+	qoz_outb(qoztmp,qoz_R_FIFO,fifo << 1);    
-+	qoz_waitbusy(qoztmp);
-+    
-+	if (debug > 1)
-+	    printk(KERN_INFO "qozap: card %d stport %d TX [ ", qoztmp->cardno, stport + 1);
-+	/* copy frame to fifo */
-+    	for (x=0;x<qoztmp->ztdev->chans[stport][chan].bytes2transmit;x++) {
-+	    if (debug > 1)
-+	        printk("%#x ",qoztmp->dtxbuf[stport][x]);
-+    	    qoz_outb(qoztmp,qoz_A_FIFO_DATA0,qoztmp->dtxbuf[stport][x]);
-+	}
-+	if (debug > 1)
-+	    printk("] %d bytes\n",qoztmp->ztdev->chans[stport][chan].bytes2transmit);
-+
-+	if (qoztmp->ztdev->chans[stport][chan].eoftx == 1) {
-+	    /* transmit HDLC frame */
-+    	    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x1);    
-+    	    qoz_waitbusy(qoztmp);
-+	}
-+    }
-+    return 0;
-+}
-+
-+static int qoz_fifo_tx(struct qoz_card *qoztmp, char fifo) {
-+    int stport = fifo / 2;
-+    int chan = fifo % 2;
-+
-+    /* select fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,0x80 | (fifo << 1));    
-+    qoz_waitbusy(qoztmp);
-+    /* transmit 8 bytes of transparent data */
-+    qoz_outdw(qoztmp,qoz_A_FIFO_DATA0,*((unsigned int *) &qoztmp->txbuf[stport][chan][0]));
-+    qoz_outdw(qoztmp,qoz_A_FIFO_DATA0,*((unsigned int *) &qoztmp->txbuf[stport][chan][4]));
-+	    
-+    return 0;
-+}
-+
-+static int qoz_dfifo_rx(struct qoz_card *qoztmp, int stport) {
-+    unsigned char f1=1,f2=1,data,stat;
-+    unsigned char of1=0,of2=0;
-+    int len,i;
-+    unsigned short z1=1,z2=1;
-+    unsigned short oz1=0,oz2=0;
-+    char fifo = 0;
-+    char offset = 0;
-+
-+    if (qoztmp->type == 0xb552) {
-+	offset = 24;
-+    } else {
-+	offset = 28;
-+    }
-+
-+    fifo = stport + offset;
-+    // select rx fifo
-+    
-+    qoz_outb(qoztmp,qoz_R_FIFO,(fifo << 1) | 1);    
-+    qoz_waitbusy(qoztmp);
-+
-+    while ((of1 != f1) && (of2 != f2)) {
-+        of1 = f1;
-+        of2 = f2;
-+        f1 = qoz_inb(qoztmp,qoz_A_F1) & 0xf;
-+        f2 = qoz_inb(qoztmp,qoz_A_F2) & 0xf;
-+    }
-+    
-+    if (f1 == f2) {
-+	/* no frame */
-+	qoztmp->st[stport].drx--;
-+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
-+	return 0;
-+    }
-+    
-+    while ((oz1 != z1) && (oz2 != z2)) {
-+        oz1 = z1;
-+        oz2 = z2;
-+	if (qoztmp->type != 0xb552) {
-+    	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x7ff;
-+	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x7ff;
-+	} else {
-+    	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x3ff;
-+	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x3ff;
-+	}
-+    }
-+    
-+    if (qoztmp->type == 0xb552) {
-+	len = z1 - z2;
-+	if (len < 0) {
-+	    len += qoz_DFIFO_SIZE8;
-+	}
-+    } else {
-+	len = z1 - z2;
-+	if (len < 0) {
-+	    len += qoz_DFIFO_SIZE4;
-+	}
-+    }
-+
-+    if (len > qoz_DFIFO_SIZE4) {
-+	printk(KERN_INFO "\nqozap: buffer overflow in D channel RX!\n");
-+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
-+	qoztmp->ztdev->chans[stport][2].eofrx = 0;
-+    } else {
-+	if (debug > 1) printk(KERN_INFO "qozap: card %d span %d RX [ ", qoztmp->cardno, stport + 1);
-+	for (i=0; i<len; i++) {
-+    	    data = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
-+	    qoztmp->drxbuf[stport][i] = data;
-+	    if (debug > 1) printk("%#x ",data);
-+	}
-+	if (debug > 1) printk("] %d bytes\n", len);
-+	qoztmp->ztdev->chans[stport][2].bytes2receive = i;
-+	qoztmp->ztdev->chans[stport][2].eofrx = 1;
-+    }
-+
-+    stat = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
-+    if (stat != 0x0) {
-+	// bad CRC, skip it
-+	printk(KERN_INFO "qozap: CRC error for HDLC frame on card %d (cardID %d) S/T port %d\n",qoztmp->cardno, qoztmp->cardID, stport+1);
-+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
-+	qoztmp->ztdev->chans[stport][2].eofrx = 0;
-+//        zt_qevent_nolock(&qoztmp->ztdev->chans[stport][2], ZT_EVENT_BADFCS);
-+    }
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x1);    
-+    qoz_waitbusy(qoztmp);
-+
-+    /* frame recevived */
-+    if (qoztmp->st[stport].drx > 0) { 
-+	qoztmp->st[stport].drx--;
-+    } else {
-+	printk(KERN_INFO "qozap: trying to receive too much (card %d span %d drx %d)\n", qoztmp->cardno, stport+1, qoztmp->st[stport].drx);
-+	qoztmp->st[stport].drx = 0;
-+    }
-+    return 0;
-+}
-+
-+
-+static int qoz_fifo_rx(struct qoz_card *qoztmp, char fifo) {
-+    int stport = fifo / 2;
-+    int chan = fifo % 2;
-+    unsigned char data;
-+    int len,i;
-+    unsigned short z1=1,z2=1;
-+    unsigned short oz1=0,oz2=0;
-+    int mumbojumbo=0;
-+
-+        /* select rx fifo */
-+	qoz_outb(qoztmp,qoz_R_FIFO,0x80 | (fifo << 1) | 1);    
-+        qoz_waitbusy(qoztmp);
-+    
-+	while ((oz1 != z1) && (oz2 != z2)) {
-+	    oz1 = z1;
-+	    oz2 = z2;
-+	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x7f;
-+    	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x7f;
-+	}
-+	len = z1 - z2;
-+	if (len < 0) {
-+	    len += qoz_FIFO_SIZE;
-+	}
-+	if (len > 2 * ZT_CHUNKSIZE) {
-+	    mumbojumbo = len - (2 * ZT_CHUNKSIZE);
-+	    len = ZT_CHUNKSIZE;
-+	    for (i=0;i<mumbojumbo;i++) {
-+    		data = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
-+	    }
-+	    qoztmp->clicks++;
-+	    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;
-+	    }
-+	}
-+	if (len < ZT_CHUNKSIZE) {
-+//	    printk(KERN_INFO "qozap: not enough to receive (%d bytes)\n",len);
-+	    return 0;
-+	} else {
-+	    if (bloop) {
-+		*((unsigned int *) &qoztmp->txbuf[stport][chan][0]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
-+	        *((unsigned int *) &qoztmp->txbuf[stport][chan][4]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
-+	    } else {
-+		*((unsigned int *) &qoztmp->rxbuf[stport][chan][0]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
-+	        *((unsigned int *) &qoztmp->rxbuf[stport][chan][4]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
-+	    }
-+	}
-+	if (bloop == 0)
-+	    zt_ec_chunk(&qoztmp->ztdev->spans[stport].chans[chan], qoztmp->ztdev->spans[stport].chans[chan].readchunk, qoztmp->ztdev->spans[stport].chans[chan].writechunk);
-+
-+//    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,qoztmp->st[stport].dbufi,f1,f2,z1,z2,len,stat,hdlc);    
-+    return 0;
-+}
-+
-+
-+static inline void qoz_run(struct qoz_card *qoztmp) {
-+    int s=0;
-+    if (qoztmp->ztdev != NULL) {
-+	for (s=0;s<qoztmp->stports;s++) {
-+	if (!bloop) {
-+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
-+		/* oh zaptel! tell us what to transmit... */
-+    		zt_transmit(&qoztmp->ztdev->spans[s]);
-+	        /* B1 xmit */
-+		qoz_fifo_tx(qoztmp, s * 2);
-+		/* B2 xmit */
-+		qoz_fifo_tx(qoztmp, (s * 2) + 1);
-+
-+		if ((qoztmp->st[s].layer1state != 7) && (qoztmp->ztdev->chans[s][2].bytes2transmit > 0) && (qoztmp->st[s].nt_mode != 1)) {
-+		    if (qoztmp->st[s].t3 == -1) {
-+			printk(KERN_INFO "qozap: activating layer 1, span %d\n",s);
-+			qoztmp->st[s].t3 = 0;
-+			qoz_outb(qoztmp,qoz_R_ST_SEL, s);
-+			qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60); 
-+		    } else {
-+		    }
-+		}
-+		
-+		/* D xmit */
-+		if (qoztmp->ztdev->spans[s].alarms != ZT_ALARM_RED) {
-+		    qoz_dfifo_tx(qoztmp, s);
-+		} else {
-+		    if ((qoztmp->st[s].t3 == -1) && (qoztmp->st[s].t4 == -1) && (qoztmp->st[s].layer1state == 3) && (qoztmp->st[s].nt_mode != 1)) {
-+			/* clear alarms */
-+			printk(KERN_INFO "qozap: clearing alarms on span %d\n",s);
-+			qoztmp->ztdev->spans[s].alarms = ZT_ALARM_NONE;
-+			zt_alarm_notify(&qoztmp->ztdev->spans[s]);
-+		    }
-+		}
-+
-+		qoztmp->ztdev->chans[s][2].bytes2receive = 0;
-+		qoztmp->ztdev->chans[s][2].bytes2transmit = 0;
-+		qoztmp->ztdev->chans[s][2].eofrx = 0;
-+		qoztmp->ztdev->chans[s][2].eoftx = 0;
-+
-+	    }
-+
-+	    /* B1 receive */
-+	    qoz_fifo_rx(qoztmp,(s*2));
-+	    /* B2 receive */
-+	    qoz_fifo_rx(qoztmp,(s*2)+1);
-+	    /* d-chan data */
-+	    if (qoztmp->st[s].drx > 0) {
-+	        if (debug > 2)
-+		    printk(KERN_CRIT "qozap: card %d st[%d].drx = %d\n", qoztmp->cardno, s, qoztmp->st[s].drx);
-+		qoz_dfifo_rx(qoztmp, s);
-+	    }
-+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
-+	        /* oh zaptel! thou shall receive! */
-+		zt_receive(&(qoztmp->ztdev->spans[s]));
-+	    }
-+	} else {
-+	    // loop
-+	    /* B1 receive */
-+	    qoz_fifo_rx(qoztmp,(s*2));
-+	    /* B2 receive */
-+	    qoz_fifo_rx(qoztmp,(s*2)+1);
-+	    /* d-chan data */
-+/*	    if (qoztmp->st[s].drx > 0) {
-+	        if (debug > 2)
-+		    printk(KERN_CRIT "qozap: card %d st[%d].drx = %d\n", qoztmp->cardno, s, qoztmp->st[s].drx);
-+		qoz_dfifo_rx(qoztmp, s);
-+	    } 
-+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
-+		zt_receive(&(qoztmp->ztdev->spans[s]));
-+	    }
-+*/
-+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
-+		/* oh zaptel! tell us what to transmit... */
-+    	//	zt_transmit(&qoztmp->ztdev->spans[s]);
-+	        /* B1 xmit */
-+		qoz_fifo_tx(qoztmp, s * 2);
-+		/* B2 xmit */
-+		qoz_fifo_tx(qoztmp, (s * 2) + 1);
-+		/* D xmit */
-+//		qoz_dfifo_tx(qoztmp, s);
-+
-+		qoztmp->ztdev->chans[s][2].bytes2receive = 0;
-+		qoztmp->ztdev->chans[s][2].bytes2transmit = 0;
-+		qoztmp->ztdev->chans[s][2].eofrx = 0;
-+		qoztmp->ztdev->chans[s][2].eoftx = 0;
-+
-+	    }
-+	}
-+	} 
-+    }
-+}
-+
-+#ifdef LINUX26
-+static irqreturn_t qoz_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
-+#else
-+static void qoz_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
-+#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;
-+
-+    if (!qoztmp) {
-+#ifdef LINUX26
-+		return IRQ_NONE;
-+#else
-+		return;
-+#endif		
-+    }
-+
-+    if ((!qoztmp->pci_io) || (!qoztmp->ioport)) {
-+	    printk(KERN_CRIT "qozap: no pci mem/io\n");
-+#ifdef LINUX26
-+		return IRQ_NONE;
-+#else
-+		return;
-+#endif		
-+    }
-+    if (qoztmp->dead) {
-+#ifdef LINUX26
-+	return IRQ_RETVAL(1);
-+#else
-+	return;
-+#endif		
-+    }
-+
-+    
-+#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!
-+#ifdef RELAXED_LOCKING
-+	spin_unlock(&(qoztmp->lock));
-+#else
-+	spin_unlock_irqrestore(&(qoztmp->lock), flags);
-+#endif
-+#ifdef LINUX26
-+		return IRQ_NONE;
-+#else
-+		return;
-+#endif		
-+    }
-+    /* state machine irq */
-+    if (irq_sci != 0) {
-+	if (debug > 1) {
-+	    printk(KERN_INFO "R_BERT_STA = %#x\n", qoz_inb(qoztmp, qoz_R_BERT_STA) & 7);
-+	}
-+	for (st=0;st<qoztmp->stports;st++) {
-+	    if (irq_sci & (1 << st)) {
-+		qoz_outb(qoztmp,qoz_R_ST_SEL,st);
-+		l1state = qoz_inb(qoztmp,qoz_A_ST_RD_STA) & 0xf;
-+		if (debug > 1) {
-+		    printk(KERN_INFO "A_ST_RD_STA = %#x\n", qoz_inb(qoztmp, qoz_A_ST_RD_STA));
-+		}
-+		qoztmp->st[st].layer1state = l1state;
-+		if (qoztmp->st[st].nt_mode == 1) {
-+		    if (debug)
-+			printk(KERN_INFO "card %d span %d state G%d (A_ST_RD_STA = %#x)\n",qoztmp->cardno,st+1,l1state,qoz_inb(qoztmp,qoz_A_ST_RD_STA));
-+		    // NT state machine
-+		    if (l1state == 3) {
-+			// keep layer1 up!
-+			if (qoztmp->stports == 8) {
-+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [NT] Layer 1 ACTIVATED (G%d)",qoztmp->cardno ,st + 1, l1state);
-+			} else {
-+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d) Layer 1 ACTIVATED (G%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
-+			}
-+			qoz_outb(qoztmp,qoz_A_ST_WR_STA,3 | 0x10 );
-+			qoztmp->leds[st] = 1;
-+		    } else {
-+			if (qoztmp->stports == 8) {
-+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [NT] Layer 1 DEACTIVATED (G%d)",qoztmp->cardno ,st + 1, l1state);
-+			} else {
-+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d) Layer 1 DEACTIVATED (G%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
-+			}
-+			qoztmp->leds[st] = 0;
-+		    }
-+		} else {
-+		    if (debug)
-+			printk(KERN_INFO "card %d span %d state F%d (A_ST_RD_STA = %#x)\n",qoztmp->cardno,st+1,l1state,qoz_inb(qoztmp,qoz_A_ST_RD_STA));
-+		    // TE state machine
-+		    if (l1state == 3) {
-+			if (qoztmp->st[st].t3 > -1)  {
-+			    /* keep layer1 up, if the span is started. */
-+			    if (qoztmp->ztdev->spans[st].flags & ZT_FLAG_RUNNING) {
-+printk("qozap: re-activating layer1 span %d\n", st);
-+    				qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60);
-+			    }
-+			} else {
-+printk("qozap: not re-activating layer1 span %d\n", st);
-+    				qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x40);
-+			    /* if we tried to activate layer 1 and it failed make this an alarm */
-+//			    qoztmp->ztdev->spans[st].alarms = ZT_ALARM_RED;
-+//			    zt_alarm_notify(&qoztmp->ztdev->spans[st]);
-+			    /* if the network shuts us down in idle mode dont make this an alarm */
-+			}
-+			qoztmp->leds[st] = 0;
-+			if (qoztmp->stports == 8) {
-+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
-+			} else {
-+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
-+			}
-+		    } else if (l1state == 7) {
-+			/* activation complete, stop timer t3 */
-+			qoztmp->st[st].t3 = -1;
-+			qoztmp->ztdev->spans[st].alarms = ZT_ALARM_NONE;
-+			zt_alarm_notify(&qoztmp->ztdev->spans[st]);
-+			qoztmp->leds[st] = 1;
-+			if (qoztmp->stports == 8) {
-+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 ACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
-+			} else {
-+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 ACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
-+			}
-+		    } else if (l1state == 8) {
-+			/* lost framing */
-+			printk(KERN_INFO "qozap: starting t4 for span %d\n", st);
-+			qoztmp->st[st].t4 = 0;
-+		    } else {
-+			if (qoztmp->stports == 8) {
-+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
-+			} else {
-+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
-+			}    
-+		    }
-+		}
-+		
-+	    }
-+	}
-+    }
-+
-+
-+    // misc irq
-+    if (status & 0x40) {
-+	irq_misc = qoz_inb(qoztmp,qoz_R_IRQ_MISC);
-+	if (irq_misc & 0x2)  {
-+	    // qozap timer
-+	    qoztmp->ticks++;
-+	    qoz_run(qoztmp);
-+	    if (qoztmp->ticks % 100) {
-+		qoz_doLEDs(qoztmp);
-+	    }
-+    	    if (qoztmp->ticks % 40) { 
-+		/* you thought that 42 was the answer.... */
-+		qoz_doWD(qoztmp);
-+	    }
-+	    if (qoztmp->ticks > 1000) {
-+		qoztmp->ticks = 0;
-+		for (j=0;j<qoztmp->stports;j++) {
-+		    /* t3 */
-+		    if (qoztmp->st[j].t3 >= 0) {
-+			qoztmp->st[j].t3++;
-+		    }
-+		    if (qoztmp->st[j].nt_mode != 1) {
-+			if ((qoztmp->st[j].t3 > qoz_T3) && (qoztmp->st[j].layer1state != 7)) {
-+			    /* deactivate layer 1 */
-+			    printk(KERN_INFO "qozap: t3 timer expired for span %d\n", j);
-+			    qoz_outb(qoztmp,qoz_R_ST_SEL, j);
-+			    qoz_outb(qoztmp,qoz_A_ST_WR_STA, 0x40 );
-+			    qoztmp->st[j].t3 = -1;
-+			    qoztmp->ztdev->spans[j].alarms = ZT_ALARM_RED;
-+			    zt_alarm_notify(&qoztmp->ztdev->spans[j]);
-+			    qoz_waitbusy(qoztmp);
-+			}
-+		    }
-+		    /* t4 */
-+		    if (qoztmp->st[j].t4 >= 0) {
-+			qoztmp->st[j].t4++;
-+		    }
-+		    if (qoztmp->st[j].nt_mode != 1) {
-+			if ((qoztmp->st[j].t4 > qoz_T4) && (qoztmp->st[j].layer1state != 7)) {
-+			    /* deactivate layer 1 */
-+			    printk(KERN_INFO "qozap: t4 timer expired for span %d\n", j);
-+			    qoz_outb(qoztmp,qoz_R_ST_SEL, j);
-+			    qoz_outb(qoztmp,qoz_A_ST_WR_STA, 0x40 );
-+			    qoztmp->st[j].t4 = -1;
-+			    qoztmp->ztdev->spans[j].alarms = ZT_ALARM_RED;
-+			    zt_alarm_notify(&qoztmp->ztdev->spans[j]);
-+			    qoz_waitbusy(qoztmp);
-+			}
-+		    }
-+		}
-+	    }
-+	}
-+	if (irq_misc & 0x4) {
-+	//    printk(KERN_INFO "qozap proc/nonproc irq\n");
-+	}
-+    }
-+    if (status & 0x80) {
-+	/* fifo irq */
-+	irq_foview = qoz_inb(qoztmp,qoz_R_IRQ_OVIEW);
-+        if (qoztmp->type == 0xb552) {
-+	    if (irq_foview & 0x60) {
-+		offset = 0;
-+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL6);
-+		for (i=0; i < 8; i++) {
-+		    if (fi & (1 << i)) {
-+			st = offset + (i / 2);
-+			if (i % 2) {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
-+				qoztmp->st[st].drx += 1;			
-+			} else {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
-+			}
-+		    }
-+		}
-+	    }
-+	    if (irq_foview & 0x80) {
-+		offset = 4;
-+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL7);
-+		for (i=0; i < 8; i++) {
-+		    if (fi & (1 << i)) {
-+			st = offset + (i / 2);
-+			if (i % 2) {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
-+				qoztmp->st[st].drx += 1;			
-+			} else {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
-+			}
-+		    }
-+		}
-+	    }
-+	} else {
-+	    if (irq_foview & 0x80) {
-+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL7);
-+		for (i=0; i < 8; i++) {
-+		    if (fi & (1 << i)) {
-+			st = i / 2;
-+			if (i % 2) {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
-+				qoztmp->st[st].drx += 1;			
-+			} else {
-+			    if (debug > 2) 
-+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
-+			}
-+		    }
-+		}
-+	    }
-+	}
-+    }
-+    
-+#ifdef RELAXED_LOCKING
-+    spin_unlock(&(qoztmp->lock));
-+#else
-+    spin_unlock_irqrestore(&(qoztmp->lock), flags);
-+#endif
-+#ifdef LINUX26
-+	return IRQ_RETVAL(1);
-+#endif		
-+}
-+
-+static int ztqoz_open(struct zt_chan *chan) {
-+//    printk(KERN_INFO "qozap: channel %d opened.\n",chan->channo);
-+#ifndef LINUX26
-+    MOD_INC_USE_COUNT;
-+#else
-+    try_module_get(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int ztqoz_close(struct zt_chan *chan) {
-+//    printk(KERN_INFO "qozap: channel %d closed.\n",chan->channo);
-+#ifndef LINUX26
-+    MOD_DEC_USE_COUNT;
-+#else
-+    module_put(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int ztqoz_rbsbits(struct zt_chan *chan, int bits) {
-+    return 0;
-+}
-+
-+static int ztqoz_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
-+        switch(cmd) {
-+        default:
-+                return -ENOTTY;
-+        }
-+        return 0;
-+}
-+
-+static int ztqoz_startup(struct zt_span *span) {
-+    struct zt_qoz *qozt = span->pvt;
-+    struct qoz_card *qoztmp = qozt->card;
-+    unsigned long flags;
-+    int alreadyrunning;
-+    int i=0;
-+    int offset = 0;
-+    
-+    if (qoztmp == NULL) {
-+	printk(KERN_INFO "qozap: no card for span at startup!\n");
-+    }
-+    
-+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-+//    printk(KERN_CRIT "already running %d flags %d\n", alreadyrunning, span->flags);
-+
-+    if (!alreadyrunning) {
-+	span->chans[2].flags &= ~ZT_FLAG_HDLC;
-+	span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
-+    
-+	/* setup B channel buffers (8 bytes each) */
-+	for (i=0; i<2 ; i++) {
-+	    memset(qoztmp->rxbuf[span->offset][i],0x0,sizeof(qoztmp->rxbuf[span->offset][i]));
-+    	    span->chans[i].readchunk = qoztmp->rxbuf[span->offset][i];
-+    	    memset(qoztmp->txbuf[span->offset][i],0x0,sizeof(qoztmp->txbuf[span->offset][i]));
-+	    span->chans[i].writechunk = qoztmp->txbuf[span->offset][i];
-+	}
-+	/* setup D channel buffer */
-+    	memset(qoztmp->dtxbuf[span->offset],0x0,sizeof(qoztmp->dtxbuf[span->offset]));
-+	span->chans[2].writechunk = qoztmp->dtxbuf[span->offset];
-+	qoztmp->ztdev->chans[span->offset][2].maxbytes2transmit = sizeof(qoztmp->dtxbuf[span->offset]);
-+
-+	memset(qoztmp->drxbuf[span->offset],0x0,sizeof(qoztmp->drxbuf[span->offset]));
-+    	span->chans[2].readchunk = qoztmp->drxbuf[span->offset];
-+
-+	span->flags |= ZT_FLAG_RUNNING;
-+    } else {
-+//	printk(KERN_CRIT "already running\n");
-+	return 0;
-+    }
-+
-+    spin_lock_irqsave(&qoztmp->lock,flags);
-+    // irqs off
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
-+
-+    if (qoztmp->type == 0xb552) {
-+	offset = 24;
-+    } else {
-+	offset = 28;
-+    }
-+
-+    /* setup D-FIFO TX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset + offset) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0xD);
-+    qoz_outb(qoztmp,qoz_A_SUBCH_CFG,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) + 2) << 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    /* setup D-FIFO RX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset + offset) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0xD);
-+    qoz_outb(qoztmp,qoz_A_SUBCH_CFG,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,(((span->offset * 4) + 2) << 1) | 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    /* setup B1-FIFO TX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset * 2) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,(span->offset * 4) << 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    /* setup B1-FIFO RX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) << 1) | 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    /* setup B2-FIFO TX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) + 1) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) + 1) << 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    /* setup B2-FIFO RX */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(((span->offset * 2) + 1) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_CHANNEL,((((span->offset) * 4) + 1) << 1) | 1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
-+
-+    if (debug)
-+        printk(KERN_INFO "qozap: starting card %d span %d/%d.\n",qoztmp->cardno,span->spanno,span->offset);
-+    
-+    /* activate layer 1 */
-+    qoz_outb(qoztmp,qoz_R_ST_SEL,span->offset);
-+    if (qoztmp->st[span->offset].nt_mode == 1) {
-+	// NT mode
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL0,0x7);
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL1,0x0);
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL2,0x3);
-+	qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,0x60 | CLKDEL_NT);
-+    } else {
-+	// TE mode
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL0,0x3);
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL1,0x0);
-+	qoz_outb(qoztmp,qoz_A_ST_CTRL2,0x3);
-+	if (qoztmp->type == 0xb550) {
-+	    qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,CLKDEL_TE);
-+	} else {
-+	    qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,CLKDEL_TE + 1);
-+	}
-+    }
-+    qoztmp->st[span->offset].t3 = 0;
-+    qoztmp->st[span->offset].t4 = -1;
-+    
-+    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,0x80); 
-+    } else {
-+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x0); 
-+    }
-+    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
-+    } else {
-+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60); // start Activation
-+    }
-+
-+    /* enable irqs */
-+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 8 | 1); 
-+    return 0;
-+}
-+
-+static int ztqoz_shutdown(struct zt_span *span) {
-+    struct zt_qoz *ztqoz = span->pvt;
-+    struct qoz_card *qoztmp = ztqoz->card;
-+    int alreadyrunning;
-+    int offset = 0;
-+    
-+    if (qoztmp == NULL) {
-+	printk(KERN_CRIT "qozap: qoztmp == NULL!\n");
-+	return 0;
-+	
-+    }
-+
-+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-+    
-+    if (!alreadyrunning) {
-+	return 0;
-+    }
-+
-+//    printk(KERN_CRIT "qozap: stopping card %d port %d.\n",qoztmp->cardno, span->offset + 1);
-+
-+    // turn off irqs for all fifos
-+    if (qoztmp->type == 0xb552) {
-+	offset = 24;
-+    } else {
-+	offset = 28;
-+    }
-+
-+    /* disable D TX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset + offset) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
-+
-+    /* disable D RX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset + offset) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x1);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
-+
-+    /* disable B1 TX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset * 2) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
-+
-+    /* disable B1 RX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
-+
-+    /* disable B2 TX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,(((span->offset) * 2) + 1) << 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
-+
-+    /* disable B2 RX fifo */
-+    qoz_outb(qoztmp,qoz_R_FIFO,((((span->offset) * 2) + 1) << 1) | 1);
-+    qoz_waitbusy(qoztmp);
-+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
-+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0); 
-+
-+    span->flags &= ~ZT_FLAG_RUNNING;
-+
-+    /* Deactivate Layer 1 */
-+    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,0x40); 
-+    } else {
-+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x40);
-+    }
-+
-+
-+//    printk(KERN_CRIT "qozap: card %d span %d/%d down.\n",qoztmp->cardno,span->spanno,span->offset);
-+    return 0;
-+}
-+
-+static int ztqoz_maint(struct zt_span *span, int cmd) {
-+    return 0;
-+}
-+
-+static int ztqoz_chanconfig(struct zt_chan *chan,int sigtype) {
-+//    printk(KERN_INFO "chan_config sigtype=%d\n",sigtype);
-+    return 0;
-+}
-+
-+static int ztqoz_spanconfig(struct zt_span *span,struct zt_lineconfig *lc) {
-+//    span->lineconfig = lc->lineconfig;
-+    return 0;
-+}
-+
-+static int ztqoz_initialize(struct zt_qoz *ztqoz) {
-+    struct qoz_card *qoztmp = ztqoz->card;
-+    int i=0,s=0;
-+    
-+    for (s=0; s < ztqoz->card->stports; s++) {
-+	memset(&ztqoz->spans[s],0,sizeof(struct zt_span)); // you never can tell...
-+	sprintf(ztqoz->spans[s].name,"ztqoz/%d/%d",qoz_dev_count + 1,s + 1);
-+	if (ztqoz->card->stports == 8) {
-+	    if (qoztmp->st[s].nt_mode == 1){
-+		sprintf(ztqoz->spans[s].desc,"octoBRI PCI ISDN Card %d Span %d [NT]",qoztmp->cardno,s + 1);
-+	    } else {
-+		sprintf(ztqoz->spans[s].desc,"octoBRI PCI ISDN Card %d Span %d [TE]",qoztmp->cardno,s + 1);
-+	    }
-+	} else {
-+	    if (ztqoz->card->cardID < 0xff) {
-+		if (qoztmp->st[s].nt_mode == 1){
-+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d)",qoztmp->cardno,s + 1,ztqoz->card->cardID);
-+		} else {
-+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d)",qoztmp->cardno,s + 1,ztqoz->card->cardID);
-+		}
-+	    } else {
-+		if (qoztmp->st[s].nt_mode == 1){
-+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [NT]",qoztmp->cardno,s + 1);
-+		} else {
-+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [TE]",qoztmp->cardno,s + 1);
-+		}
-+	    }
-+	}
-+
-+        ztqoz->spans[s].spanconfig = ztqoz_spanconfig;
-+        ztqoz->spans[s].chanconfig = ztqoz_chanconfig;
-+        ztqoz->spans[s].startup = ztqoz_startup;
-+        ztqoz->spans[s].shutdown = ztqoz_shutdown;
-+        ztqoz->spans[s].maint = ztqoz_maint;
-+        ztqoz->spans[s].rbsbits = ztqoz_rbsbits;
-+        ztqoz->spans[s].open = ztqoz_open;
-+        ztqoz->spans[s].close = ztqoz_close;
-+        ztqoz->spans[s].ioctl = ztqoz_ioctl;
-+
-+        ztqoz->spans[s].chans = ztqoz->chans[s];
-+        ztqoz->spans[s].channels = 3;
-+        ztqoz->spans[s].deflaw = ZT_LAW_ALAW;
-+        ztqoz->spans[s].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS; // <--- this is really BS
-+        init_waitqueue_head(&ztqoz->spans[s].maintq);
-+        ztqoz->spans[s].pvt = ztqoz;
-+        ztqoz->spans[s].offset = s;
-+
-+	for (i=0; i < ztqoz->spans[s].channels; i++) {
-+	    memset(&(ztqoz->chans[s][i]),0x0,sizeof(struct zt_chan));
-+	    sprintf(ztqoz->chans[s][i].name,"ztqoz%d/%d/%d",qoz_dev_count + 1,s + 1,i + 1);
-+	    ztqoz->chans[s][i].pvt = ztqoz;
-+	    ztqoz->chans[s][i].sigcap =  ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_SF;
-+	    ztqoz->chans[s][i].chanpos = i + 1; 
-+	}
-+
-+	if (zt_register(&ztqoz->spans[s],0)) {
-+	    printk(KERN_INFO "qozap: unable to register zaptel span %d!\n",s+1);
-+	    return -1;
-+	}
-+//	 printk(KERN_INFO "qozap: registered zaptel span %d.\n",s+1);
-+    }
-+
-+    return 0;
-+}
-+
-+int qoz_findCards(unsigned int pcidid) {
-+    struct pci_dev *tmp;
-+    struct qoz_card *qoztmp = NULL;
-+    struct zt_qoz *ztqoz = NULL;
-+    int i=0;
-+    unsigned char dips=0;
-+    int cid=0;
-+    int modes=0;
-+    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
-+    while (tmp != NULL) {
-+	multi_qoz = tmp;	// skip this next time.
-+
-+	if (pci_enable_device(tmp)) {
-+	    multi_qoz = NULL;
-+	    return -1;
-+	}
-+
-+	qoztmp = kmalloc(sizeof(struct qoz_card),GFP_KERNEL);
-+	if (!qoztmp) {
-+	    printk(KERN_WARNING "qozap: unable to kmalloc!\n");
-+	    pci_disable_device(tmp);
-+	    multi_qoz = NULL;
-+	    return -ENOMEM;
-+	}
-+	memset(qoztmp, 0x0, sizeof(struct qoz_card));
-+	
-+	spin_lock_init(&qoztmp->lock);
-+	qoztmp->pcidev = tmp;
-+	qoztmp->pcibus = tmp->bus->number;
-+	qoztmp->pcidevfn = tmp->devfn; 
-+
-+	if (!tmp->irq) {
-+	    printk(KERN_WARNING "qozap: no irq!\n");
-+	} else {
-+	    qoztmp->irq = tmp->irq;
-+	}
-+
-+	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;
-+	    return -EIO;
-+	}
-+
-+	qoztmp->ioport = tmp->resource[0].start;
-+	if (!qoztmp->ioport) {
-+	    printk(KERN_WARNING "qozap: no ioport!\n");
-+	    pci_disable_device(tmp);
-+	    multi_qoz = NULL;
-+	    return -EIO;
-+	}
-+	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");
-+	    kfree(qoztmp);
-+	    pci_disable_device(tmp);
-+	    multi_qoz = NULL;
-+	    return -EIO;
-+	}
-+
-+	qoztmp->pci_io = ioremap((ulong) qoztmp->pci_io_phys, 256);
-+	
-+	pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
-+
-+	// disable ints
-+	qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
-+
-+	ztqoz = kmalloc(sizeof(struct zt_qoz),GFP_KERNEL);
-+	if (!ztqoz) {
-+	    printk(KERN_INFO "qozap: unable to kmalloc!\n");
-+	    qoz_shutdownCard(qoztmp);
-+	    kfree(qoztmp);
-+	    multi_qoz = NULL;
-+	    return -ENOMEM;
-+	}
-+	memset(ztqoz, 0x0, sizeof(struct zt_qoz));
-+
-+	if (pcidid == PCI_DEVICE_ID_CCD_M) {
-+	    qoztmp->stports = 8;
-+	} else {
-+	    qoztmp->stports = 4;
-+	}
-+	
-+
-+        if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
-+	//    printk(KERN_INFO "MODES = %#x.\n",modes);
-+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x80 | 0x40);
-+	    dips = (qoz_inb(qoztmp,qoz_R_GPIO_IN1) >> 5);
-+	    cid = 7;
-+	    for (i=0;i<3;i++) {
-+	        if ((dips & (1 << i)) != 0) {
-+	    	cid -= (1 << (2-i));
-+	        }
-+	    }
-+	//	printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
-+        } else if ((tmp->subsystem_device==0xb550) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
-+	//    printk(KERN_INFO "MODES = %#x.\n",modes);
-+	    dips = ~(qoz_inb(qoztmp,qoz_R_GPI_IN3) & 7);
-+	    cid = 0;
-+	    for (i=0;i<3;i++) {
-+	        if ((dips & (1 << i)) != 0) {
-+	    	cid += (1 << i);
-+	        }
-+	    }
-+	printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
-+        } else {
-+	    cid = 0xff;
-+        }
-+
-+	if (ports == -1) {
-+    	    if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
-+		modes = qoz_inb(qoztmp,qoz_R_GPI_IN3) >> 4;
-+    	    } else if ((tmp->subsystem_device==0xb550) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
-+		qoz_outb(qoztmp,qoz_R_GPIO_SEL,0xff);
-+		qoz_outb(qoztmp,qoz_R_GPIO_EN0,0x00);
-+		printk(KERN_CRIT "gpio_in0 %#x \n", qoz_inb(qoztmp,qoz_R_GPIO_IN0));
-+		printk(KERN_CRIT "gpio_in1 %#x \n", qoz_inb(qoztmp,qoz_R_GPIO_IN1));
-+		printk(KERN_CRIT "gpi_in1 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN1));
-+		printk(KERN_CRIT "gpi_in2 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN2));
-+		printk(KERN_CRIT "gpi_in3 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN3));
-+		modes = qoz_inb(qoztmp,qoz_R_GPI_IN3) >> 4;	    
-+	    } else {
-+		modes = 0; // assume TE mode
-+	    }
-+	} else {
-+	    modes = ports >> totalBRIs;
-+	}
-+
-+	if (pcidid == PCI_DEVICE_ID_CCD_M4) {
-+	    switch (tmp->subsystem_device) {
-+		case 0x08b4:
-+			if (ports == -1) ports = 0; /* assume TE mode if no ports param */
-+			printk(KERN_INFO
-+		        "qozap: CologneChip HFC-4S evaluation board configured at io port %#x IRQ %d HZ %d\n",
-+		          (u_int) qoztmp->ioport,
-+		        qoztmp->irq, HZ);
-+		    break;
-+		case 0xb520:
-+			printk(KERN_INFO
-+		        "qozap: Junghanns.NET quadBRI card configured at io port %#x IRQ %d HZ %d CardID %d\n",
-+		          (u_int) qoztmp->ioport,
-+		        qoztmp->irq, HZ, cid);
-+		    break;
-+		case 0xb550:
-+			printk(KERN_INFO
-+		        "qozap: Junghanns.NET quadBRI (Version 2.0) card configured at io port %#x IRQ %d HZ %d CardID %d\n",
-+		          (u_int) qoztmp->ioport,
-+		        qoztmp->irq, HZ, cid);
-+		    break;
-+	    } 
-+	    totalBRIs += 4;
-+	} else {
-+	    switch (tmp->subsystem_device) {
-+		case 0xb552:
-+		    printk(KERN_INFO
-+		       "qozap: Junghanns.NET octoBRI card configured at io port %#x IRQ %d HZ %d\n",
-+		       (u_int) qoztmp->ioport,
-+		       qoztmp->irq, HZ);
-+	        break;
-+		default:
-+		    printk(KERN_INFO
-+		       "qozap: wtf\n");
-+		    if (qoztmp->pcidev != NULL) {
-+    			pci_disable_device(qoztmp->pcidev);
-+		    }
-+		    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, 0);	
-+		    free_irq(qoztmp->irq,qoztmp);
-+		    kfree(qoztmp);
-+		    qoztmp = NULL;
-+		    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
-+		    continue;
-+		break;		
-+	    } 
-+	    totalBRIs += 8;
-+	}
-+
-+	qoztmp->cardID = cid;
-+	qoztmp->type = tmp->subsystem_device;
-+
-+	printk(KERN_INFO "qozap: S/T ports: %d [",qoztmp->stports);
-+	for (i=0;i<qoztmp->stports;i++) {
-+	    if ((modes & (1 << i)) != 0) {
-+	        qoztmp->st[i].nt_mode = 1;
-+	        printk(" NT");
-+	    } else {
-+	        qoztmp->st[i].nt_mode = 0;
-+	        printk(" TE");
-+	    }
-+	}
-+	printk(" ]\n");
-+	
-+	ztqoz->card = qoztmp;
-+	qoztmp->ztdev = ztqoz;
-+
-+	qoz_registerCard(qoztmp);
-+	tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
-+    }
-+    return 0;
-+}
-+
-+
-+int qoz_sortCards(void) {
-+    int changed=0,tmpcardno;
-+    struct qoz_card *tmpcard,*tmpcard2;
-+    spin_lock(&registerlock);
-+    do {
-+	changed = 0;
-+	tmpcard = qoz_dev_list;
-+	while (tmpcard != NULL) {
-+	    if (tmpcard->prev) {
-+		if (tmpcard->prev->cardID > tmpcard->cardID) {
-+		    tmpcardno = tmpcard->prev->cardno;
-+		    tmpcard->prev->cardno = tmpcard->cardno; 
-+		    tmpcard->cardno = tmpcardno;
-+		
-+		    tmpcard2 = tmpcard->prev;
-+		    if (tmpcard2->prev) {
-+			tmpcard2->prev->next = tmpcard;
-+		    } else {
-+			qoz_dev_list = tmpcard;
-+		    }
-+		    if (tmpcard->next) {
-+			tmpcard->next->prev = tmpcard2;
-+		    } 
-+		    tmpcard2->next = tmpcard->next;
-+		    tmpcard->prev = tmpcard2->prev;
-+		    tmpcard->next = tmpcard2;
-+		    tmpcard2->prev = tmpcard;
-+		    changed = 1;
-+		    tmpcard = tmpcard2;
-+		}
-+	    }
-+	    tmpcard = tmpcard->next;
-+	}
-+    } while (changed == 1);
-+    spin_unlock(&registerlock);
-+    return 0;
-+}
-+
-+int qoz_zapCards(void) {
-+    struct qoz_card *tmpcard;
-+    tmpcard = qoz_dev_list;
-+    while (tmpcard != NULL) {
-+	ztqoz_initialize(tmpcard->ztdev);
-+	qoz_resetCard(tmpcard);
-+	tmpcard = tmpcard->next;
-+    }
-+    return 0;
-+}
-+
-+
-+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, pcmslave %d.\n",qoz_dev_count, totalBRIs, bloop, pcmslave);
-+    }
-+    return 0;
-+}
-+
-+void cleanup_module(void) {
-+    struct qoz_card *tmpcard,*tmplist;
-+    int i=0;
-+    tmplist = qoz_dev_list;
-+    while (tmplist != NULL) {
-+	tmplist->dead = 1;
-+	qoz_undoWD(tmplist);
-+	qoz_shutdownCard(tmplist);
-+	tmplist = tmplist->next;
-+    }
-+    tmplist = qoz_dev_list;
-+    spin_lock(&registerlock);
-+    while (tmplist != NULL) {
-+	tmpcard = tmplist->next;
-+	kfree(tmplist);
-+	i++;
-+	tmplist = tmpcard;
-+    }
-+    spin_unlock(&registerlock);
-+    printk(KERN_INFO "qozap: shutdown %d multiBRI cards.\n", i);
-+}
-+#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.6/qozap/qozap.h /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/qozap.h
---- zaptel-1.2.6/qozap/qozap.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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
-+#define qoz_DFIFO_SIZE8	1024
-+
-+typedef struct qoz_span {
-+    unsigned char nt_mode;
-+    unsigned char btx;
-+    unsigned char bswapped;
-+    unsigned char drx;
-+    int t3;
-+    int t4;
-+    unsigned char layer1state;
-+} qoz_span;
-+
-+typedef struct qoz_regs {
-+    unsigned char fifo_en;
-+    unsigned char ctmt;
-+    unsigned char int_m1;
-+    unsigned char int_m2;
-+    unsigned char sctrl;
-+    unsigned char sctrl_e;
-+    unsigned char sctrl_r;
-+    unsigned char connect;
-+    unsigned char trm;
-+    unsigned char mst_mode;
-+} qoz_regs;
-+
-+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;
-+    unsigned int pcidevfn;
-+    struct pci_dev *pcidev;
-+    struct zt_qoz *ztdev;
-+    unsigned char rxbuf[qoz_SPANS][2][ZT_CHUNKSIZE];
-+    unsigned char txbuf[qoz_SPANS][2][ZT_CHUNKSIZE];
-+    unsigned char drxbuf[qoz_SPANS][qoz_DFIFO_SIZE4];
-+    unsigned char dtxbuf[qoz_SPANS][qoz_DFIFO_SIZE4];
-+    unsigned char stports;
-+    unsigned int ticks;
-+    unsigned int clicks;
-+    unsigned int type;
-+    unsigned int wdp;
-+    struct qoz_card *next;
-+    struct qoz_card *prev;
-+} qoz_card;
-+
-+
-+typedef struct zt_qoz {
-+    unsigned int usecount;
-+    struct zt_span spans[qoz_SPANS];
-+    struct zt_chan chans[qoz_SPANS][3];
-+    struct qoz_card *card;
-+} zt_qoz;
-+
-+#define qoz_outb_io(a,b,c) \
-+    outw((b), ((a)->ioport+4)); \
-+    outb((c), ((a)->ioport));
-+
-+#define qoz_inb_io(a,b) ({ outw((b), (a)->ioport+4); inb((a)->ioport); })
-+
-+#define qoz_outw_io(a,b,c) \
-+    outw((b), ((a)->ioport+4)); \
-+    outw((c), ((a)->ioport));
-+
-+#define qoz_inw_io(a,b) ({ outw((b), (a)->ioport+4); inw((a)->ioport); })
-+
-+#define qoz_outdw_io(a,b,c) \
-+    outw((b), ((a)->ioport+4)); \
-+    outl((c), ((a)->ioport));
-+
-+#define qoz_indw_io(a,b) ({ outw((b), (a)->ioport+4); inl((a)->ioport); })
-+
-+#define qoz_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
-+#define qoz_inb(a,b) (readb((a)->pci_io+(b)))
-+
-+#define qoz_outw(a,b,c) (writew((c),(a)->pci_io+(b)))
-+#define qoz_inw(a,b) (readw((a)->pci_io+(b)))
-+
-+#define qoz_outdw(a,b,c) (writel((c),(a)->pci_io+(b)))
-+#define qoz_indw(a,b) (readl((a)->pci_io+(b)))
-+
-+
-+/* Write only registers */
-+#define qoz_A_CH_MSK	0xF4
-+#define qoz_A_CHANNEL 	0xFC
-+#define qoz_A_CON_HDLC	0xFA
-+#define qoz_A_CONF	0xD1
-+#define qoz_A_FIFO_SEQ	0xFD
-+#define qoz_R_INC_RES_FIFO	0x0E
-+#define qoz_A_IRQ_MSK	0xFF
-+#define qoz_A_SL_CFG	0xD0
-+#define qoz_A_ST_B1_TX	0x3C
-+#define qoz_A_ST_B2_TX	0x3D
-+#define qoz_A_ST_CLK_DLY	0x37
-+#define qoz_A_ST_CTRL0	0x31
-+#define qoz_A_ST_CTRL1	0x32
-+#define qoz_A_ST_CTRL2	0x33
-+#define qoz_A_ST_D_TX	0x3E
-+#define qoz_A_ST_SQ_WR	0x34
-+#define qoz_A_ST_WR_STA	0x30
-+#define qoz_A_SUBCH_CFG	0xFB
-+#define qoz_R_BERT_WD_MD	0x1B
-+#define qoz_R_BRG_CTRL	0x45
-+#define qoz_R_BRG_MD	0x47
-+#define qoz_R_BRG_PCM_CFG	0x02
-+#define qoz_R_BRG_TIM_SEL01	0x4C
-+#define qoz_R_BRG_TIM_SEL23	0x4D
-+#define qoz_R_BRG_TIM_SEL45	0x4E
-+#define qoz_R_BRG_TIM_SEL67	0x4F
-+#define qoz_R_BRG_TIM0	0x48
-+#define qoz_R_BRG_TIM1	0x49
-+#define qoz_R_BRG_TIM2	0x4A
-+#define qoz_R_BRG_TIM3	0x4B
-+#define qoz_R_CIRM	0x00
-+#define qoz_R_CONF_EN	0x18
-+#define qoz_R_CTRL	0x01
-+#define qoz_R_DTMF0	0x1C
-+#define qoz_R_DTMF1	0x1D
-+#define qoz_R_FIFO_MD	0x0D
-+#define qoz_R_FIFO	0x0F
-+#define qoz_R_FIRST_FIFO	0x0B
-+#define qoz_R_FSM_IDX	0x0F
-+#define qoz_R_GPIO_EN0	0x42
-+#define qoz_R_GPIO_EN1	0x43
-+#define qoz_R_GPIO_OUT0	0x40
-+#define qoz_R_GPIO_OUT1	0x41
-+#define qoz_R_GPIO_SEL	0x44
-+#define qoz_R_IRQ_CTRL	0x13
-+#define qoz_R_IRQMSK_MISC	0x11
-+#define qoz_R_PCM_MD0	0x14
-+#define qoz_R_PCM_MD1	0x15
-+#define qoz_R_PCM_MD2	0x15
-+#define qoz_R_PWM_MD	0x46
-+#define qoz_R_PWM0	0x38
-+#define qoz_R_PWM1	0x39
-+#define qoz_R_RAM_ADDR0	0x08
-+#define qoz_R_RAM_ADDR1	0x09
-+#define qoz_R_RAM_ADDR2	0x0A
-+#define qoz_R_RAM_MISC	0x0C
-+#define qoz_R_SCI_MSK	0x12
-+#define qoz_R_SH0H	0x15
-+#define qoz_R_SH0L	0x15
-+#define qoz_R_SH1H	0x15
-+#define qoz_R_SH1L	0x15
-+#define qoz_R_SL_SEL0	0x15
-+#define qoz_R_SL_SEL1	0x15
-+#define qoz_R_SL_SEL2	0x15
-+#define qoz_R_SL_SEL3	0x15
-+#define qoz_R_SL_SEL4	0x15
-+#define qoz_R_SL_SEL5	0x15
-+#define qoz_R_SL_SEL6	0x15
-+#define qoz_R_SL_SEL7	0x15
-+#define qoz_R_SLOT	0x10
-+#define qoz_R_ST_SEL	0x16
-+#define qoz_R_ST_SYNC	0x17
-+#define qoz_R_TI_WD	0x1A
-+
-+/* Read only registers */
-+#define qoz_A_F1	0x0C
-+#define qoz_A_F12	0x0C
-+#define qoz_A_F2	0x0D
-+#define qoz_A_ST_B1_RX	0x3C
-+#define qoz_A_ST_B2_TX	0x3D
-+#define qoz_A_ST_D_RX	0x3E
-+#define qoz_A_ST_E_RX	0x3F
-+#define qoz_A_ST_RD_STA	0x30
-+#define qoz_A_ST_SQ_RD	0x34
-+#define qoz_A_Z1	0x04
-+#define qoz_A_Z12	0x04
-+#define qoz_A_Z1H	0x05
-+#define qoz_A_Z1L	0x04
-+#define qoz_A_Z2	0x06
-+#define qoz_A_Z2H	0x07
-+#define qoz_A_Z2L	0x06
-+#define qoz_R_BERT_ECH	0x1B
-+#define qoz_R_BERT_ECL	0x1A
-+#define qoz_R_BERT_STA	0x17
-+#define qoz_R_CHIP_ID	0x16
-+#define qoz_R_CHIP_RV	0x1F
-+#define qoz_R_CONF_OFLOW	0x14
-+#define qoz_R_F0_CNTH	0x19
-+#define qoz_R_F0_CNTL	0x18
-+#define qoz_R_GPI_IN0	0x44
-+#define qoz_R_GPI_IN1	0x45
-+#define qoz_R_GPI_IN2	0x46
-+#define qoz_R_GPI_IN3	0x47
-+#define qoz_R_GPIO_IN0	0x40
-+#define qoz_R_GPIO_IN1	0x41
-+#define qoz_R_INT_DATA	0x88
-+#define qoz_R_IRQ_FIFO_BL0	0xC8
-+#define qoz_R_IRQ_FIFO_BL1	0xC9
-+#define qoz_R_IRQ_FIFO_BL2	0xCA
-+#define qoz_R_IRQ_FIFO_BL3	0xCB
-+#define qoz_R_IRQ_FIFO_BL4	0xCC
-+#define qoz_R_IRQ_FIFO_BL5	0xCD
-+#define qoz_R_IRQ_FIFO_BL6	0xCE
-+#define qoz_R_IRQ_FIFO_BL7	0xCF
-+#define qoz_R_IRQ_MISC	0x11
-+#define qoz_R_IRQ_OVIEW	0x10
-+#define qoz_R_RAM_USE	0x15
-+#define qoz_R_SCI	0x12
-+#define qoz_R_STATUS	0x1C
-+
-+/* Read/Write registers */
-+#define qoz_A_FIFO_DATA0_NOINC	0x84
-+#define qoz_A_FIFO_DATA0	0x80
-+#define qoz_A_FIFO_DATA1_NOINC	0x84
-+#define qoz_A_FIFO_DATA1	0x80
-+#define qoz_A_FIFO_DATA2_NOINC	0x84
-+#define qoz_A_FIFO_DATA2	0x80
-+#define qoz_R_RAM_DATA	0xC0
-+
-+#define PCI_DEVICE_ID_CCD_M	0x16b8
-+#define PCI_DEVICE_ID_CCD_M4	0x08b4
-+#define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
-+#define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
-+
-+#define HFC8S_CHIP_ID	0x80
-+#define HFC4S_CHIP_ID	0xC0
-+
-+#define qoz_WD_P0	0x000000
-+#define qoz_WD_P1	0x808080
-+#define qoz_WD_P2	0x404040
-+
-+#define qoz_T3		3
-+#define qoz_T4		1
-+
-+
-diff -urNad zaptel-1.2.6/qozap/TODO /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/TODO
---- zaptel-1.2.6/qozap/TODO	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/TODO	2006-02-22 20:41:09.000000000 +0200
-@@ -0,0 +1,9 @@
-+- native-native bridging
-+- onchip dtmf
-+- E channel support for full debug
-+
-+
-+t3 (5ms max)
-+
-+t4 (500ms) layer 1 down/up
-+
-diff -urNad zaptel-1.2.6/qozap/zapata.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zapata.conf
---- zaptel-1.2.6/qozap/zapata.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zapata.conf	2006-04-10 12:56:52.000000000 +0300
-@@ -0,0 +1,51 @@
-+;
-+; Zapata telephony interface
-+;
-+; Configuration file
-+
-+[channels]
-+;
-+; Default language
-+;
-+;language=en
-+;
-+; Default context
-+;
-+;
-+switchtype = euroisdn
-+
-+; p2mp TE mode (for connecting ISDN lines in point-to-multipoint mode)
-+signalling = bri_cpe_ptmp
-+; p2p TE mode (for connecting ISDN lines in point-to-point mode)
-+;signalling = bri_cpe
-+; p2mp NT mode (for connecting ISDN phones in point-to-multipoint mode)
-+;signalling = bri_net_ptmp
-+; p2p NT mode (for connecting an ISDN pbx in point-to-point mode)
-+;signalling = bri_net
-+
-+pridialplan = local
-+prilocaldialplan = dynamic
-+nationalprefix = 0
-+internationalprefix = 00
-+
-+priindication = passthrough
-+
-+echocancel = yes
-+
-+context=demo
-+group = 1
-+; S/T port 1
-+channel => 1-2
-+
-+group = 2
-+; S/T port 2
-+channel => 4-5
-+
-+group = 3
-+; S/T port 3
-+channel => 7-8
-+
-+group = 4
-+; S/T port 4
-+channel => 10-11
-+
-diff -urNad zaptel-1.2.6/qozap/zapata.conf.octoBRI /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zapata.conf.octoBRI
---- zaptel-1.2.6/qozap/zapata.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zapata.conf.octoBRI	2006-04-10 12:57:02.000000000 +0300
-@@ -0,0 +1,67 @@
-+;
-+; Zapata telephony interface
-+;
-+; Configuration file
-+
-+[channels]
-+;
-+; Default language
-+;
-+;language=en
-+;
-+; Default context
-+;
-+;
-+switchtype = euroisdn
-+
-+; p2mp TE mode (for connecting ISDN lines in point-to-multipoint mode)
-+signalling = bri_cpe_ptmp
-+; p2p TE mode (for connecting ISDN lines in point-to-point mode)
-+;signalling = bri_cpe
-+; p2mp NT mode (for connecting ISDN phones in point-to-multipoint mode)
-+;signalling = bri_net_ptmp
-+; p2p NT mode (for connecting an ISDN pbx in point-to-point mode)
-+;signalling = bri_net
-+
-+pridialplan = local
-+prilocaldialplan = dynamic
-+nationalprefix = 0
-+internationalprefix = 00
-+
-+priindication = passthrough
-+
-+echocancel = yes
-+
-+context=demo
-+group = 1
-+; S/T port 1
-+channel => 1-2
-+
-+group = 2
-+; S/T port 2
-+channel => 4-5
-+
-+group = 3
-+; S/T port 3
-+channel => 7-8
-+
-+group = 4
-+; S/T port 4
-+channel => 10-11
-+
-+group = 5
-+; S/T port 5
-+channel => 13-14
-+
-+group = 6
-+; S/T port 6
-+channel => 16-17
-+
-+group = 7
-+; S/T port 7
-+channel => 19-20
-+
-+group = 8
-+; S/T port 8
-+channel => 22-23
-+
-diff -urNad zaptel-1.2.6/qozap/zaptel.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zaptel.conf
---- zaptel-1.2.6/qozap/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zaptel.conf	2006-02-22 20:41:09.000000000 +0200
-@@ -0,0 +1,18 @@
-+loadzone=nl
-+defaultzone=nl
-+# qozap span definitions
-+# most of the values should be bogus because we are not really zaptel
-+span=1,1,3,ccs,ami
-+span=2,2,3,ccs,ami
-+span=3,0,3,ccs,ami
-+span=4,0,3,ccs,ami
-+
-+bchan=1,2
-+dchan=3
-+bchan=4,5
-+dchan=6
-+bchan=7,8
-+dchan=9
-+bchan=10,11
-+dchan=12
-+
-diff -urNad zaptel-1.2.6/qozap/zaptel.conf.octoBRI /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zaptel.conf.octoBRI
---- zaptel-1.2.6/qozap/zaptel.conf.octoBRI	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/qozap/zaptel.conf.octoBRI	2006-02-22 20:41:09.000000000 +0200
-@@ -0,0 +1,30 @@
-+loadzone=nl
-+defaultzone=nl
-+# qozap span definitions
-+# most of the values should be bogus because we are not really zaptel
-+span=1,1,3,ccs,ami
-+span=2,0,3,ccs,ami
-+span=3,0,3,ccs,ami
-+span=4,0,3,ccs,ami
-+span=5,1,3,ccs,ami
-+span=6,0,3,ccs,ami
-+span=7,0,3,ccs,ami
-+span=8,0,3,ccs,ami
-+
-+bchan=1,2
-+dchan=3
-+bchan=4,5
-+dchan=6
-+bchan=7,8
-+dchan=9
-+bchan=10,11
-+dchan=12
-+bchan=13,14
-+dchan=15
-+bchan=16,17
-+dchan=18
-+bchan=19,20
-+dchan=21
-+bchan=22,23
-+dchan=24
-+
-diff -urNad zaptel-1.2.6/zaphfc/LICENSE /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/LICENSE
---- zaptel-1.2.6/zaphfc/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/LICENSE	2003-08-19 04:24:43.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.6/zaphfc/Makefile /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/Makefile
---- zaptel-1.2.6/zaphfc/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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/zaptel.h ] && echo "-I$(BRISTUFFBASE)/zaptel")
-+RTAI = $(shell [ -f /usr/realtime/include/rtai.h ] && echo "-DRTAITIMING -I/usr/realtime/include")
-+
-+HOSTCC=gcc
-+
-+CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE 
-+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) $(RTAI) -Wall
-+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)
-+
-+
-+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)
-+
-+OBJS=zaphfc.o
-+
-+MODULES=zaphfc
-+
-+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
-+
-+
-+zaphfc.o: zaphfc.c zaphfc.h
-+	$(CC) -c zaphfc.c $(KFLAGS)
-+
-+clean:	
-+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
-+	rm -rf .tmp_versions
-+
-+test: all
-+	modprobe zaptel
-+	insmod ./zaphfc.o
-+	cat /proc/interrupts
-+	sleep 1
-+	cat /proc/interrupts
-+	rmmod zaphfc
-+	rmmod zaptel
-+
-+load:	load$(BUILDVER)
-+
-+loadNT:	load$(BUILDVER)NT
-+
-+load-debug:	load$(BUILDVER)-debug
-+
-+loadNT-debug:	load$(BUILDVER)NT-debug
-+
-+loadlinux24: all
-+	modprobe zaptel
-+	insmod ./zaphfc.o
-+	ztcfg -v
-+
-+loadlinux24-debug: all
-+	modprobe zaptel
-+	insmod ./zaphfc.o debug=1
-+	ztcfg -v
-+
-+loadlinux26: linux26
-+	modprobe zaptel
-+	insmod ./zaphfc.ko
-+	ztcfg -v
-+
-+loadlinux26-debug: linux26
-+	modprobe zaptel
-+	insmod ./zaphfc.ko debug=1
-+	ztcfg -v
-+
-+loadlinux24NT: all
-+	modprobe zaptel
-+	insmod ./zaphfc.o modes=1
-+	ztcfg -v
-+
-+loadlinux24NT-debug: all
-+	modprobe zaptel
-+	insmod ./zaphfc.o modes=1 debug=1
-+	ztcfg -v
-+
-+loadlinux26NT: linux26
-+	modprobe zaptel
-+	insmod ./zaphfc.ko modes=1
-+	ztcfg -v
-+
-+loadlinux26NT-debug: linux26
-+	modprobe zaptel
-+	insmod ./zaphfc.ko modes=1 debug=1
-+	ztcfg -v
-+
-+unload: 
-+	-rmmod zaphfc zaptel
-+
-+zaphfc.ko: zaphfc.c zaphfc.h
-+
-+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
-+
-+install:	install$(BUILDVER)
-+
-+installlinux26:
-+	install -D -m 644 zaphfc.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.ko
-+
-+installlinux24:
-+	install -D -m 644 zaphfc.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.o
-+
-diff -urNad zaptel-1.2.6/zaphfc/zapata.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/zapata.conf
---- zaptel-1.2.6/zaphfc/zapata.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/zapata.conf	2005-02-26 19:24:32.000000000 +0200
-@@ -0,0 +1,38 @@
-+;
-+; Zapata telephony interface
-+;
-+; Configuration file
-+
-+[channels]
-+;
-+; Default language
-+;
-+;language=en
-+;
-+; Default context
-+;
-+;
-+switchtype = euroisdn
-+; p2mp TE mode
-+signalling = bri_cpe_ptmp
-+
-+; p2p TE mode
-+;signalling = bri_cpe
-+; p2mp NT mode
-+;signalling = bri_net_ptmp
-+; p2p NT mode
-+;signalling = bri_net
-+
-+pridialplan = dynamic
-+prilocaldialplan = local
-+nationalprefix = 0
-+internationalprefix = 00
-+
-+echocancel=yes
-+echotraining = 100
-+echocancelwhenbridged=yes
-+
-+immediate=yes
-+group = 1
-+context=demo
-+channel => 1-2
-diff -urNad zaptel-1.2.6/zaphfc/zaphfc.c /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/zaphfc.c
---- zaptel-1.2.6/zaphfc/zaphfc.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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
-+ *
-+ * kernel module inspired by HFC PCI ISDN4Linux and Zaptel drivers
-+ *
-+ * Copyright (C) 2002, 2003, 2004, 2005 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>
-+#ifdef RTAITIMING
-+#include <asm/io.h>
-+#include <rtai.h>
-+#include <rtai_sched.h>
-+#include <rtai_fifos.h>
-+#endif
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <zaptel.h>
-+#include "zaphfc.h"
-+
-+#if CONFIG_PCI
-+
-+#define CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
-+#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
-+
-+typedef struct {
-+        int vendor_id;
-+        int device_id;
-+        char *vendor_name;
-+        char *card_name;
-+} PCI_ENTRY;
-+
-+static const PCI_ENTRY id_list[] =
-+{
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
-+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
-+        {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
-+        {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
-+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
-+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
-+        {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
-+        {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
-+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
-+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
-+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
-+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
-+	{0x182d, 0x3069,"Sitecom","Isdn 128 PCI"},
-+        {0, 0, NULL, NULL},
-+};
-+
-+static struct hfc_card *hfc_dev_list = NULL;
-+static int hfc_dev_count = 0;
-+static int modes = 0; // all TE
-+static int debug = 0;
-+static struct pci_dev *multi_hfc = NULL;
-+static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
-+
-+void hfc_shutdownCard(struct hfc_card *hfctmp) {
-+    unsigned long flags;
-+
-+    if (hfctmp == NULL) {
-+	return;
-+    }
-+
-+    if (hfctmp->pci_io == NULL) {
-+	return;
-+    }
-+    
-+    spin_lock_irqsave(&hfctmp->lock,flags);
-+
-+    printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
-+
-+    /* Clear interrupt mask */
-+    hfctmp->regs.int_m2 = 0;
-+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
-+
-+    /* Reset pending interrupts */
-+    hfc_inb(hfctmp, hfc_INT_S1);
-+
-+    /* Wait for interrupts that might still be pending */
-+    spin_unlock_irqrestore(&hfctmp->lock, flags);
-+    set_current_state(TASK_UNINTERRUPTIBLE);
-+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
-+    spin_lock_irqsave(&hfctmp->lock,flags);
-+
-+    /* Remove interrupt handler */
-+    if (hfctmp->irq) {
-+	free_irq(hfctmp->irq, hfctmp);
-+    }
-+
-+    /* Soft-reset the card */
-+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
-+
-+    spin_unlock_irqrestore(&hfctmp->lock, flags);
-+    set_current_state(TASK_UNINTERRUPTIBLE);
-+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
-+    spin_lock_irqsave(&hfctmp->lock,flags);
-+
-+    hfc_outb(hfctmp,hfc_CIRM,0);	// softreset off
-+
-+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);	// disable memio and bustmaster
-+
-+    if (hfctmp->fifomem != NULL) {
-+        kfree(hfctmp->fifomem);
-+    }
-+    iounmap((void *) hfctmp->pci_io);
-+    hfctmp->pci_io = NULL;
-+    if (hfctmp->pcidev != NULL) {
-+        pci_disable_device(hfctmp->pcidev);
-+    }
-+    spin_unlock_irqrestore(&hfctmp->lock,flags);
-+    if (hfctmp->ztdev != NULL) {
-+	zt_unregister(&hfctmp->ztdev->span);
-+	kfree(hfctmp->ztdev);
-+	printk(KERN_INFO "unregistered from zaptel.\n");
-+    }
-+}
-+
-+void hfc_resetCard(struct hfc_card *hfctmp) {
-+    unsigned long flags;
-+
-+    spin_lock_irqsave(&hfctmp->lock,flags);
-+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
-+    hfctmp->regs.int_m2 = 0;
-+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
-+
-+//    printk(KERN_INFO "zaphfc: resetting card.\n");
-+    pci_set_master(hfctmp->pcidev);
-+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET);	// softreset on
-+    spin_unlock_irqrestore(&hfctmp->lock, flags);
-+
-+    set_current_state(TASK_UNINTERRUPTIBLE);
-+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
-+    hfc_outb(hfctmp, hfc_CIRM, 0);	// softreset off
-+
-+    set_current_state(TASK_UNINTERRUPTIBLE);
-+    schedule_timeout((20 * HZ) / 1000);	// wait 20 ms
-+    if (hfc_inb(hfctmp,hfc_STATUS) & hfc_STATUS_PCI_PROC) {
-+	printk(KERN_WARNING "zaphfc: hfc busy.\n");
-+    }
-+
-+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
-+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D;	/* only D fifos enabled */
-+    hfctmp->regs.fifo_en = 0;	/* no fifos enabled */
-+    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
-+
-+    hfctmp->regs.trm = 2;
-+    hfc_outb(hfctmp, hfc_TRM, hfctmp->regs.trm);
-+
-+    if (hfctmp->regs.nt_mode == 1) {
-+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
-+    } else {
-+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */
-+    }
-+    hfctmp->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
-+    hfc_outb(hfctmp, hfc_SCTRL_E, hfctmp->regs.sctrl_e);	/* S/T Auto awake */
-+    hfctmp->regs.bswapped = 0;	/* no exchange */
-+
-+    hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
-+    hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
-+
-+    hfctmp->regs.int_m1 = 0;
-+    hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
-+
-+#ifdef RTAITIMING
-+    hfctmp->regs.int_m2 = 0;
-+#else
-+    hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS;
-+#endif
-+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
-+
-+    /* Clear already pending ints */
-+    hfc_inb(hfctmp, hfc_INT_S1);
-+
-+    if (hfctmp->regs.nt_mode == 1) {
-+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_NT;	/* set tx_lo mode, error in datasheet ! */
-+    } else {
-+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;	/* set tx_lo mode, error in datasheet ! */
-+    }
-+
-+    hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER;	/* HFC Master Mode */
-+    hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
-+
-+    hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
-+    hfctmp->regs.sctrl_r = 3;
-+    hfc_outb(hfctmp, hfc_SCTRL_R, hfctmp->regs.sctrl_r);
-+
-+    hfctmp->regs.connect = 0;
-+    hfc_outb(hfctmp, hfc_CONNECT, hfctmp->regs.connect);
-+
-+    hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);	// bit order
-+
-+    /* Finally enable IRQ output */
-+#ifndef RTAITIMING
-+    hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
-+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
-+#endif
-+
-+    /* clear pending ints */
-+    hfc_inb(hfctmp, hfc_INT_S1); 
-+    hfc_inb(hfctmp, hfc_INT_S2);
-+}
-+
-+void hfc_registerCard(struct hfc_card *hfccard) {
-+    spin_lock(&registerlock);
-+    if (hfccard != NULL) {
-+	hfccard->cardno = hfc_dev_count++;
-+	hfccard->next = hfc_dev_list;
-+	hfc_dev_list = hfccard;
-+    }
-+    spin_unlock(&registerlock);
-+}
-+
-+static void hfc_btrans(struct hfc_card *hfctmp, char whichB) {
-+    // we are called with irqs disabled from the irq handler
-+    int count, maxlen, total;
-+    unsigned char *f1, *f2;
-+    unsigned short *z1, *z2, newz1;
-+    int freebytes;
-+
-+    if (whichB == 1) {
-+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1);
-+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2);
-+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4));
-+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4));
-+    } else {
-+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1);
-+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2);
-+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4));
-+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4));
-+    }
-+
-+    freebytes = *z2 - *z1;
-+    if (freebytes <= 0) {
-+	freebytes += hfc_B_FIFO_SIZE;
-+    }
-+    count = ZT_CHUNKSIZE;
-+
-+    total = count;
-+    if (freebytes < count) {
-+	hfctmp->clicks++;
-+	/* only spit out this warning once per second to not make things worse! */
-+	if (hfctmp->clicks > 100) {
-+	    printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2);
-+	    hfctmp->clicks = 0;
-+	}
-+	return;
-+    }
-+    
-+    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1;
-+    if (maxlen > count) {
-+        maxlen = count;
-+    }
-+    newz1 = *z1 + total;
-+    if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; }
-+
-+	if (whichB == 1) {
-+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen);
-+	} else {
-+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen);
-+	}
-+	
-+	count -= maxlen;
-+	if (count > 0) {
-+	// Buffer wrap
-+	    if (whichB == 1) {
-+	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count);
-+	    } else {
-+	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count);
-+	    }
-+	}
-+
-+    *z1 = newz1;	/* send it now */
-+
-+//    if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
-+    return;    
-+}
-+
-+static void hfc_brec(struct hfc_card *hfctmp, char whichB) {
-+    // we are called with irqs disabled from the irq handler
-+    int count, maxlen, drop;
-+    volatile unsigned char *f1, *f2;
-+    volatile unsigned short *z1, *z2, newz2;
-+    int bytes = 0;
-+
-+    if (whichB == 1) {
-+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1);
-+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2);
-+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4));
-+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
-+    } else {
-+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1);
-+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2);
-+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4));
-+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
-+    }
-+
-+    bytes = *z1 - *z2;
-+    if (bytes < 0) {
-+	bytes += hfc_B_FIFO_SIZE;
-+    }
-+    count = ZT_CHUNKSIZE;
-+    
-+    if (bytes < ZT_CHUNKSIZE) {
-+#ifndef RTAITIMING
-+	printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,ZT_CHUNKSIZE,bytes);
-+#endif
-+	return;
-+    }
-+
-+    /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */
-+    if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) {
-+	/* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */
-+	drop = bytes - ZT_CHUNKSIZE;
-+	hfctmp->clicks++;
-+	/* only spit out this warning once per second to not make things worse! */
-+	if (hfctmp->clicks > 100) {
-+	    printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop);
-+	    hfctmp->clicks = 0;
-+	}
-+	/* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */
-+	newz2 = *z2 + drop;
-+	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
-+	    newz2 -= hfc_B_FIFO_SIZE; 
-+	}
-+	*z2 = newz2;
-+    }
-+
-+    
-+    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2;
-+    if (maxlen > count) {
-+        maxlen = count;
-+    }
-+    if (whichB == 1) {
-+        memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen);
-+    } else {
-+        memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen);
-+    }
-+    newz2 = *z2 + count;
-+    if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
-+        newz2 -= hfc_B_FIFO_SIZE; 
-+    }
-+    *z2 = newz2;
-+	
-+    count -= maxlen;
-+    if (count > 0) {
-+    // Buffer wrap
-+        if (whichB == 1) {
-+	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
-+    	    memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count);
-+	} else {
-+	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
-+	    memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count);
-+	}
-+	newz2 = *z2 + count;
-+	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
-+	    newz2 -= hfc_B_FIFO_SIZE; 
-+	}
-+    }
-+
-+
-+    if (whichB == 1) {
-+	zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk);
-+    } else {
-+	zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk);
-+    }
-+    return;    
-+}
-+
-+
-+static void hfc_dtrans(struct hfc_card *hfctmp) {
-+    // we are called with irqs disabled from the irq handler
-+    int x;
-+    int count, maxlen, total;
-+    unsigned char *f1, *f2, newf1;
-+    unsigned short *z1, *z2, newz1;
-+    int frames, freebytes;
-+
-+    if (hfctmp->ztdev->chans[2].bytes2transmit == 0) {
-+	return;
-+    }
-+
-+    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1);
-+    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2);
-+    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
-+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4));
-+
-+    frames = (*f1 - *f2) & hfc_FMASK;
-+    if (frames < 0) {
-+	frames += hfc_MAX_DFRAMES + 1;
-+    }
-+
-+    if (frames >= hfc_MAX_DFRAMES) {
-+	printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n");
-+	return;
-+    }
-+
-+    freebytes = *z2 - *z1;
-+    if (freebytes <= 0) {
-+	freebytes += hfc_D_FIFO_SIZE;
-+    }
-+    count = hfctmp->ztdev->chans[2].bytes2transmit;
-+
-+    total = count;
-+    if (freebytes < count) {
-+	printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2);
-+	return;
-+    }
-+    
-+    newz1 = (*z1 + count) & hfc_ZMASK;
-+    newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	// next frame
-+    
-+    if (count > 0) {
-+	if (debug) {
-+    	    printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno);
-+	    for (x=0; x<count; x++) {
-+		printk("%#2x ",hfctmp->dtransbuf[x]);
-+	    }
-+	    if (hfctmp->ztdev->chans[2].eoftx == 1) {
-+		printk("] %d bytes\n", count);
-+	    } else {
-+		printk("..] %d bytes\n", count);
-+	    }
-+	}
-+	maxlen = hfc_D_FIFO_SIZE - *z1;
-+	if (maxlen > count) {
-+	    maxlen = count;
-+	}
-+	memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen);
-+	count -= maxlen;
-+	if (count > 0) {
-+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count);
-+	}
-+    }
-+
-+    *z1 = newz1;
-+
-+    if (hfctmp->ztdev->chans[2].eoftx == 1) {
-+	*f1 = newf1;
-+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
-+	*z1 = newz1;
-+	hfctmp->ztdev->chans[2].eoftx = 0;
-+    }
-+//    printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
-+    return;    
-+}
-+
-+/* receive a complete hdlc frame, skip broken or short frames */
-+static void hfc_drec(struct hfc_card *hfctmp) {
-+    int count=0, maxlen=0, framelen=0;
-+    unsigned char *f1, *f2, *crcstat;
-+    unsigned short *z1, *z2, oldz2, newz2;
-+
-+    hfctmp->ztdev->chans[2].bytes2receive=0;
-+    hfctmp->ztdev->chans[2].eofrx = 0;
-+
-+    /* put the received data into the zaptel buffer
-+       we'll call zt_receive() later when the timer fires. */
-+    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1);
-+    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2);
-+
-+    if (*f1 == *f2) return; /* nothing received, strange eh? */
-+
-+    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4));
-+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
-+    
-+    /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */
-+    count = *z1 - *z2;
-+    
-+    if (count < 0) { 
-+	count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */
-+    }
-+    count++;
-+    framelen = count;
-+
-+    crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1);
-+
-+    if ((framelen < 4) || (*crcstat != 0x0)) {
-+	/* the frame is too short for a valid HDLC frame or the CRC is borked */
-+	printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno);
-+	oldz2 = *z2;
-+	*f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
-+        // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!!
-+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
-+	*z2 = (oldz2 + framelen) & hfc_ZMASK;
-+	hfctmp->drecinframe = 0;
-+	hfctmp->regs.int_drec--;
-+	/* skip short or broken frames */
-+        hfctmp->ztdev->chans[2].bytes2receive = 0; 
-+	return;
-+    }
-+
-+    count -= 1;	/* strip STAT */
-+    hfctmp->ztdev->chans[2].eofrx = 1;
-+
-+    if (count + *z2 <= hfc_D_FIFO_SIZE) {
-+	maxlen = count;
-+    } else {
-+	maxlen = hfc_D_FIFO_SIZE - *z2;
-+    }
-+
-+    /* copy first part */
-+    memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen);
-+    hfctmp->ztdev->chans[2].bytes2receive += maxlen; 
-+    
-+    count -= maxlen;
-+    if (count > 0) {
-+	/* ring buffer wrapped, copy rest from start of d fifo */
-+	memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count);
-+	hfctmp->ztdev->chans[2].bytes2receive += count; 
-+    }
-+
-+    /* frame read */
-+    oldz2 = *z2;
-+    newz2 = (oldz2 + framelen) & hfc_ZMASK;
-+    *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
-+    /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */
-+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
-+    *z2 = newz2;
-+    hfctmp->drecinframe = 0;
-+    hfctmp->regs.int_drec--; 
-+}
-+
-+#ifndef RTAITIMING
-+#ifdef LINUX26
-+static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
-+#else
-+static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
-+#endif
-+    struct hfc_card *hfctmp = dev_id;
-+    unsigned long flags = 0;
-+    unsigned char stat;
-+#else
-+static void hfc_service(struct hfc_card *hfctmp) {
-+#endif
-+    struct zt_hfc *zthfc;
-+    unsigned char s1, s2, l1state;
-+    int x;
-+
-+    if (!hfctmp) {
-+#ifndef RTAITIMING
-+#ifdef LINUX26
-+		return IRQ_NONE;
-+#else
-+		return;
-+#endif		
-+#else
-+	/* rtai */
-+	return;
-+#endif
-+    }
-+
-+    if (!hfctmp->pci_io) {
-+	    printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
-+		   __FUNCTION__);
-+#ifndef RTAITIMING
-+#ifdef LINUX26
-+	    return IRQ_NONE;
-+#else
-+	    return;
-+#endif		
-+#else
-+	/* rtai */
-+	return;
-+#endif
-+    }
-+    
-+    /*	we assume a few things in this irq handler:
-+	- the hfc-pci will only generate "timer" irqs (proc/non-proc)
-+	- we need to use every 8th IRQ (to generate 1khz timing)
-+	OR
-+	- if we use rtai for timing the hfc-pci will not generate ANY irq,
-+	  instead rtai will call this "fake" irq with a 1khz realtime timer. :)
-+	- rtai will directly service the card, not like it used to by triggering
-+	  the linux irq
-+    */
-+
-+#ifndef RTAITIMING
-+    spin_lock_irqsave(&hfctmp->lock, flags);
-+    stat = hfc_inb(hfctmp, hfc_STATUS);
-+
-+    if ((stat & hfc_STATUS_ANYINT) == 0) {
-+        // maybe we are sharing the irq
-+	spin_unlock_irqrestore(&hfctmp->lock,flags);
-+#ifdef LINUX26
-+	return IRQ_NONE;
-+#else
-+	return;
-+#endif		
-+    }
-+#endif
-+
-+    s1 = hfc_inb(hfctmp, hfc_INT_S1);
-+    s2 = hfc_inb(hfctmp, hfc_INT_S2); 
-+    if (s1 != 0) {
-+	if (s1 & hfc_INTS_TIMER) {
-+	    // timer (bit 7)
-+	    // printk(KERN_CRIT "timer %d %d %d.\n", stat, s1, s2);
-+	}
-+	if (s1 & hfc_INTS_L1STATE) {
-+	    // state machine (bit 6)
-+	    // printk(KERN_CRIT "zaphfc: layer 1 state machine interrupt\n");
-+	    zthfc = hfctmp->ztdev;
-+	    l1state = hfc_inb(hfctmp,hfc_STATES)  & hfc_STATES_STATE_MASK;
-+	    if (hfctmp->regs.nt_mode == 1) {
-+		if (debug) {
-+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = G%d\n", hfctmp->cardno, l1state);
-+		}
-+		switch (l1state) {
-+		    case 3:
-+#ifdef RTAITIMING
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
-+#else
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
-+#endif
-+			break;
-+		    default:
-+#ifdef RTAITIMING
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
-+#else
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
-+#endif
-+		}
-+		if (l1state == 2) {
-+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
-+		} else if (l1state == 3) {
-+		    // fix to G3 state (see specs)
-+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
-+		}
-+	    } else {
-+		if (debug) {
-+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = F%d\n", hfctmp->cardno, l1state);
-+		}
-+		switch (l1state) {
-+		    case 7:
-+#ifdef RTAITIMING
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
-+#else
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
-+#endif
-+			break;
-+		    default:
-+#ifdef RTAITIMING
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
-+#else
-+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
-+#endif
-+		}
-+		if (l1state == 3) {
-+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
-+		}
-+	    }
-+	    
-+	}
-+	if (s1 & hfc_INTS_DREC) {
-+	    // D chan RX (bit 5)
-+	    hfctmp->regs.int_drec++;
-+	    // mr. zapata there is something for you!
-+	//    printk(KERN_CRIT "d chan rx\n");		    
-+	}
-+	if (s1 & hfc_INTS_B2REC) {
-+	    // B2 chan RX (bit 4)
-+	}
-+	if (s1 & hfc_INTS_B1REC) {
-+	    // B1 chan RX (bit 3)
-+	}
-+	if (s1 & hfc_INTS_DTRANS) {
-+	    // D chan TX (bit 2)
-+//	    printk(KERN_CRIT "zaphfc: dchan frame transmitted.\n");
-+	}
-+	if (s1 & hfc_INTS_B2TRANS) {
-+	    // B2 chan TX (bit 1)
-+	}
-+	if (s1 & hfc_INTS_B1TRANS) {
-+	    // B1 chan TX (bit 0)
-+	}
-+    }
-+#ifdef RTAITIMING
-+    /* fake an irq */
-+    s2 |= hfc_M2_PROC_TRANS;
-+#endif
-+    if (s2 != 0) {
-+	if (s2 & hfc_M2_PMESEL) {
-+	    // kaboom irq (bit 7)
-+	    printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
-+	}
-+	if (s2 & hfc_M2_GCI_MON_REC) {
-+	    // RxR monitor channel (bit 2)
-+	}
-+	if (s2 & hfc_M2_GCI_I_CHG) {
-+	    // GCI I-change  (bit 1)
-+	}
-+	if (s2 & hfc_M2_PROC_TRANS) {
-+	    // processing/non-processing transition  (bit 0)
-+	    hfctmp->ticks++;
-+#ifndef RTAITIMING
-+	    if (hfctmp->ticks > 7) {
-+		// welcome to zaptel timing :)
-+#endif
-+	    	hfctmp->ticks = 0;
-+
-+		if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
-+		    // clear dchan buffer
-+		    hfctmp->ztdev->chans[2].bytes2transmit = 0;
-+		    hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
-+
-+		    zt_transmit(&(hfctmp->ztdev->span));
-+
-+		    hfc_btrans(hfctmp,1);
-+		    hfc_btrans(hfctmp,2);
-+		    hfc_dtrans(hfctmp);
-+		}
-+
-+		hfc_brec(hfctmp,1);
-+		hfc_brec(hfctmp,2);
-+		if (hfctmp->regs.int_drec > 0) {
-+		    // dchan data to read
-+		    hfc_drec(hfctmp);
-+		    if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
-+			    if (debug) {
-+    				printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
-+				if (hfctmp->ztdev->chans[2].eofrx) {
-+				    /* dont output CRC == less user confusion */
-+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive - 2; x++) {
-+					printk("%#2x ", hfctmp->drecbuf[x]);
-+				    }
-+				    printk("] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive - 2);
-+				} else {
-+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive; x++) {
-+					printk("%#2x ", hfctmp->drecbuf[x]);
-+				    }
-+				    printk("..] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive);
-+				}
-+			    }
-+		    }
-+		} else {
-+			// hmm....ok, let zaptel receive nothing
-+		    hfctmp->ztdev->chans[2].bytes2receive = 0;
-+		}
-+		if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
-+		    zt_receive(&(hfctmp->ztdev->span));
-+		}
-+		
-+#ifndef RTAITIMING
-+	    }
-+#endif
-+	}
-+
-+    }
-+#ifndef RTAITIMING
-+    spin_unlock_irqrestore(&hfctmp->lock,flags);
-+#ifdef LINUX26
-+	return IRQ_RETVAL(1);
-+#endif		
-+#endif
-+}
-+
-+
-+static int zthfc_open(struct zt_chan *chan) {
-+    struct zt_hfc *zthfc = chan->pvt;
-+    struct hfc_card *hfctmp = zthfc->card;
-+    
-+    if (!hfctmp) {
-+    return 0;
-+    }
-+#ifndef LINUX26  
-+    MOD_INC_USE_COUNT;
-+#else
-+    try_module_get(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int zthfc_close(struct zt_chan *chan) {
-+    struct zt_hfc *zthfc = chan->pvt;
-+    struct hfc_card *hfctmp = zthfc->card;
-+
-+    if (!hfctmp) {
-+	return 0;
-+    }
-+
-+#ifndef LINUX26  
-+    MOD_DEC_USE_COUNT;
-+#else
-+    module_put(THIS_MODULE);
-+#endif
-+    return 0;
-+}
-+
-+static int zthfc_rbsbits(struct zt_chan *chan, int bits) {
-+    return 0;
-+}
-+
-+static int zthfc_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
-+        switch(cmd) {
-+        default:
-+                return -ENOTTY;
-+        }
-+        return 0;
-+}
-+
-+static int zthfc_startup(struct zt_span *span) {
-+    struct zt_hfc *zthfc = span->pvt;
-+    struct hfc_card *hfctmp = zthfc->card;
-+    int alreadyrunning;
-+    
-+    if (hfctmp == NULL) {
-+	printk(KERN_INFO "zaphfc: no card for span at startup!\n");
-+    }
-+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
-+    
-+    if (!alreadyrunning) {
-+	span->chans[2].flags &= ~ZT_FLAG_HDLC;
-+	span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
-+	
-+	span->flags |= ZT_FLAG_RUNNING;
-+
-+	hfctmp->ticks = -2;
-+	hfctmp->clicks = 0;
-+	hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
-+        hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
-+    } else {
-+	return 0;
-+    }
-+
-+    // drivers, start engines!
-+    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
-+    return 0;
-+}
-+
-+static int zthfc_shutdown(struct zt_span *span) {
-+    return 0;
-+}
-+
-+static int zthfc_maint(struct zt_span *span, int cmd) {
-+    return 0;
-+}
-+
-+static int zthfc_chanconfig(struct zt_chan *chan, int sigtype) {
-+//    printk(KERN_CRIT "chan_config sigtype=%d\n", sigtype);
-+    return 0;
-+}
-+
-+static int zthfc_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) {
-+    span->lineconfig = lc->lineconfig;
-+    return 0;
-+}
-+
-+static int zthfc_initialize(struct zt_hfc *zthfc) {
-+    struct hfc_card *hfctmp = zthfc->card;
-+    int i;
-+
-+    memset(&zthfc->span, 0x0, sizeof(struct zt_span)); // you never can tell...
-+
-+    sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
-+    if (hfctmp->regs.nt_mode == 1) {
-+#ifdef RTAITIMING
-+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1);
-+#else
-+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
-+#endif
-+    } else {
-+#ifdef RTAITIMING
-+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1);
-+#else
-+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
-+#endif
-+    }
-+
-+    zthfc->span.spanconfig = zthfc_spanconfig;
-+    zthfc->span.chanconfig = zthfc_chanconfig;
-+    zthfc->span.startup = zthfc_startup;
-+    zthfc->span.shutdown = zthfc_shutdown;
-+    zthfc->span.maint = zthfc_maint;
-+    zthfc->span.rbsbits = zthfc_rbsbits;
-+    zthfc->span.open = zthfc_open;
-+    zthfc->span.close = zthfc_close;
-+    zthfc->span.ioctl = zthfc_ioctl;
-+
-+    zthfc->span.chans = zthfc->chans;
-+    zthfc->span.channels = 3;
-+    zthfc->span.deflaw = ZT_LAW_ALAW;
-+    zthfc->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS; // <--- this is really BS
-+    zthfc->span.offset = 0;
-+    init_waitqueue_head(&zthfc->span.maintq);
-+    zthfc->span.pvt = zthfc;
-+
-+    for (i = 0; i < zthfc->span.channels; i++) {
-+	memset(&(zthfc->chans[i]), 0x0, sizeof(struct zt_chan));
-+	sprintf(zthfc->chans[i].name, "ZTHFC%d/%d/%d", hfc_dev_count + 1,0,i + 1);
-+	zthfc->chans[i].pvt = zthfc;
-+	zthfc->chans[i].sigcap =  ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_SF;
-+	zthfc->chans[i].chanpos = i + 1; 
-+    }
-+
-+    if (zt_register(&zthfc->span,0)) {
-+	printk(KERN_CRIT "unable to register zaptel device!\n");
-+	return -1;
-+    }
-+//    printk(KERN_CRIT "zaphfc: registered zaptel device!\n");
-+    return 0;
-+}
-+
-+#ifdef RTAITIMING
-+#define TICK_PERIOD  1000000
-+#define TICK_PERIOD2 1000000000
-+#define TASK_PRIORITY 1
-+#define STACK_SIZE 10000
-+
-+static RT_TASK rt_task;
-+static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS];
-+static unsigned char rtai_hfc_counter = 0;
-+
-+static void rtai_register_hfc(struct hfc_card *hfctmp) {
-+    rtai_hfc_list[rtai_hfc_counter++] = hfctmp;
-+}
-+
-+static void rtai_loop(int t) {
-+    int i=0;
-+    for (;;) {
-+	for (i=0; i < rtai_hfc_counter; i++) {
-+	    if (rtai_hfc_list[i] != NULL)
-+		hfc_service(rtai_hfc_list[i]);
-+	}
-+        rt_task_wait_period();
-+    }
-+}
-+#endif
-+
-+int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
-+    struct pci_dev *tmp;
-+    struct hfc_card *hfctmp = NULL;
-+    struct zt_hfc *zthfc = NULL;
-+
-+    tmp = pci_find_device(pcivendor, pcidevice, multi_hfc);
-+    while (tmp != NULL) {
-+	multi_hfc = tmp;	// skip this next time.
-+
-+	if (pci_enable_device(tmp)) {
-+	    multi_hfc = NULL;
-+	    return -1;
-+	}
-+	pci_set_master(tmp);
-+
-+	hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
-+	if (!hfctmp) {
-+	    printk(KERN_WARNING "zaphfc: unable to kmalloc!\n");
-+	    pci_disable_device(tmp);
-+	    multi_hfc = NULL;
-+	    return -ENOMEM;
-+	}
-+	memset(hfctmp, 0x0, sizeof(struct hfc_card));
-+	spin_lock_init(&hfctmp->lock);
-+	
-+	hfctmp->pcidev = tmp;
-+	hfctmp->pcibus = tmp->bus->number;
-+	hfctmp->pcidevfn = tmp->devfn; 
-+
-+	if (!tmp->irq) {
-+	    printk(KERN_WARNING "zaphfc: no irq!\n");
-+	} else {
-+	    hfctmp->irq = tmp->irq;
-+	}
-+
-+	hfctmp->pci_io = (char *) tmp->resource[1].start;
-+	if (!hfctmp->pci_io) {
-+	    printk(KERN_WARNING "zaphfc: no iomem!\n");
-+	    kfree(hfctmp);
-+	    pci_disable_device(tmp);
-+	    multi_hfc = NULL;
-+	    return -1;
-+	}
-+	
-+	hfctmp->fifomem = kmalloc(65536, GFP_KERNEL);
-+	if (!hfctmp->fifomem) {
-+	    printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n");
-+	    kfree(hfctmp);
-+	    pci_disable_device(tmp);
-+	    multi_hfc = NULL;
-+	    return -ENOMEM;
-+	} else {
-+	    memset(hfctmp->fifomem, 0x0, 65536);
-+	    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);
-+	}
-+
-+#ifdef RTAITIMING
-+	/* we need no stinking irq */
-+	hfctmp->irq = 0;
-+#else
-+	if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) {
-+	    printk(KERN_WARNING "zaphfc: unable to register irq\n");
-+	    kfree(hfctmp->fifomem);
-+	    kfree(hfctmp);
-+	    iounmap((void *) hfctmp->pci_io);
-+	    pci_disable_device(tmp);
-+	    multi_hfc = NULL;
-+	    return -EIO;
-+	}
-+#endif
-+
-+#ifdef RTAITIMING
-+	rtai_register_hfc(hfctmp);
-+#endif
-+	printk(KERN_INFO
-+		       "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
-+			vendor_name, card_name,
-+		       (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
-+	hfctmp->regs.int_m1 = 0;	// no ints
-+	hfctmp->regs.int_m2 = 0;	// not at all
-+	hfc_outb(hfctmp,hfc_INT_M1,hfctmp->regs.int_m1);
-+	hfc_outb(hfctmp,hfc_INT_M2,hfctmp->regs.int_m2);
-+
-+	if ((modes & (1 << hfc_dev_count)) != 0) {
-+	    printk(KERN_INFO "zaphfc: Card %d configured for NT mode\n",hfc_dev_count);
-+	    hfctmp->regs.nt_mode = 1;
-+	} else {
-+	    printk(KERN_INFO "zaphfc: Card %d configured for TE mode\n",hfc_dev_count);
-+	    hfctmp->regs.nt_mode = 0;
-+	}
-+
-+	zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL);
-+	if (!zthfc) {
-+	    printk(KERN_CRIT "zaphfc: unable to kmalloc!\n");
-+	    hfc_shutdownCard(hfctmp);
-+	    kfree(hfctmp);
-+	    multi_hfc = NULL;
-+	    return -ENOMEM;
-+	}
-+	memset(zthfc, 0x0, sizeof(struct zt_hfc));
-+
-+	zthfc->card = hfctmp;
-+	zthfc_initialize(zthfc);
-+	hfctmp->ztdev = zthfc;
-+
-+	memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
-+	hfctmp->ztdev->chans[2].readchunk = hfctmp->drecbuf;
-+
-+	memset(hfctmp->dtransbuf, 0x0, sizeof(hfctmp->dtransbuf));
-+	hfctmp->ztdev->chans[2].writechunk = hfctmp->dtransbuf;
-+
-+	memset(hfctmp->brecbuf[0], 0x0, sizeof(hfctmp->brecbuf[0]));
-+	hfctmp->ztdev->chans[0].readchunk = hfctmp->brecbuf[0];
-+	memset(hfctmp->btransbuf[0], 0x0, sizeof(hfctmp->btransbuf[0]));
-+	hfctmp->ztdev->chans[0].writechunk = hfctmp->btransbuf[0];
-+
-+	memset(hfctmp->brecbuf[1], 0x0, sizeof(hfctmp->brecbuf[1]));
-+	hfctmp->ztdev->chans[1].readchunk = hfctmp->brecbuf[1];
-+	memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
-+	hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
-+
-+
-+	hfc_registerCard(hfctmp);
-+	hfc_resetCard(hfctmp);
-+	tmp = pci_find_device(pcivendor, pcidevice, multi_hfc);
-+    }
-+    return 0;
-+}
-+
-+
-+
-+int init_module(void) {
-+    int i = 0;
-+#ifdef RTAITIMING
-+    RTIME tick_period;
-+    for (i=0; i < hfc_MAX_CARDS; i++) {
-+	rtai_hfc_list[i] = NULL;
-+    }
-+    rt_set_periodic_mode();
-+#endif
-+    i = 0;
-+    while (id_list[i].vendor_id) {
-+	multi_hfc = NULL;
-+	hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
-+	i++;
-+    }
-+#ifdef RTAITIMING
-+    for (i=0; i < hfc_MAX_CARDS; i++) {
-+        if (rtai_hfc_list[i]) {
-+	    printk(KERN_INFO
-+		       "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n",
-+			rtai_hfc_list[i]->cardno,
-+		       (u_int) rtai_hfc_list[i]->pci_io,
-+		       (u_int) rtai_hfc_list[i]->fifos,
-+		       (u_int) virt_to_bus(rtai_hfc_list[i]->fifos));
-+
-+	}
-+    }
-+    rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0);
-+    tick_period = start_rt_timer(nano2count(TICK_PERIOD));
-+    rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
-+#endif
-+    printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
-+    return 0;
-+}
-+
-+void cleanup_module(void) {
-+    struct hfc_card *tmpcard;
-+#ifdef RTAITIMING
-+    stop_rt_timer();
-+    rt_task_delete(&rt_task);
-+#endif
-+    printk(KERN_INFO "zaphfc: stop\n");
-+//    spin_lock(&registerlock);
-+    while (hfc_dev_list != NULL) {
-+	if (hfc_dev_list == NULL) break;
-+	hfc_shutdownCard(hfc_dev_list);
-+	tmpcard = hfc_dev_list;
-+	hfc_dev_list = hfc_dev_list->next;
-+	if (tmpcard != NULL) {
-+	    kfree(tmpcard);
-+	    tmpcard = NULL;
-+	    printk(KERN_INFO "zaphfc: freed one card.\n");
-+	}
-+    }
-+//    spin_unlock(&registerlock);
-+}
-+#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	
-diff -urNad zaptel-1.2.6/zaphfc/zaphfc.h /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/zaphfc.h
---- zaptel-1.2.6/zaphfc/zaphfc.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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
-+ *
-+ * kernel module based on HFC PCI ISDN4Linux and Zaptel drivers
-+ *
-+ * Copyright (C) 2002, 2003, 2004, 2005 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.
-+ *
-+ */
-+
-+/* HFC register addresses - accessed using memory mapped I/O */
-+/* For a list, see datasheet section 3.2.1 at page 21 */
-+
-+#define hfc_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
-+#define hfc_inb(a,b) (readb((a)->pci_io+(b)))
-+
-+/* GCI/IOM bus monitor registers */
-+
-+#define hfc_C_I       0x08
-+#define hfc_TRxR      0x0C
-+#define hfc_MON1_D    0x28
-+#define hfc_MON2_D    0x2C
-+
-+
-+/* GCI/IOM bus timeslot registers */
-+
-+#define hfc_B1_SSL    0x80
-+#define hfc_B2_SSL    0x84
-+#define hfc_AUX1_SSL  0x88
-+#define hfc_AUX2_SSL  0x8C
-+#define hfc_B1_RSL    0x90
-+#define hfc_B2_RSL    0x94
-+#define hfc_AUX1_RSL  0x98
-+#define hfc_AUX2_RSL  0x9C
-+
-+/* GCI/IOM bus data registers */
-+
-+#define hfc_B1_D      0xA0
-+#define hfc_B2_D      0xA4
-+#define hfc_AUX1_D    0xA8
-+#define hfc_AUX2_D    0xAC
-+
-+/* GCI/IOM bus configuration registers */
-+
-+#define hfc_MST_EMOD  0xB4
-+#define hfc_MST_MODE	 0xB8
-+#define hfc_CONNECT 	 0xBC
-+
-+
-+/* Interrupt and status registers */
-+
-+#define hfc_FIFO_EN   0x44
-+#define hfc_TRM       0x48
-+#define hfc_B_MODE    0x4C
-+#define hfc_CHIP_ID   0x58
-+#define hfc_CIRM  	 0x60
-+#define hfc_CTMT	 0x64
-+#define hfc_INT_M1  	 0x68
-+#define hfc_INT_M2  	 0x6C
-+#define hfc_INT_S1  	 0x78
-+#define hfc_INT_S2  	 0x7C
-+#define hfc_STATUS  	 0x70
-+
-+/* S/T section registers */
-+
-+#define hfc_STATES  	 0xC0
-+#define hfc_SCTRL  	 0xC4
-+#define hfc_SCTRL_E   0xC8
-+#define hfc_SCTRL_R   0xCC
-+#define hfc_SQ  	 0xD0
-+#define hfc_CLKDEL  	 0xDC
-+#define hfc_B1_REC    0xF0
-+#define hfc_B1_SEND   0xF0
-+#define hfc_B2_REC    0xF4
-+#define hfc_B2_SEND   0xF4
-+#define hfc_D_REC     0xF8
-+#define hfc_D_SEND    0xF8
-+#define hfc_E_REC     0xFC
-+
-+/* Bits and values in various HFC PCI registers */
-+
-+/* bits in status register (READ) */
-+#define hfc_STATUS_PCI_PROC   0x02
-+#define hfc_STATUS_NBUSY	  0x04 
-+#define hfc_STATUS_TIMER_ELAP 0x10
-+#define hfc_STATUS_STATINT	  0x20
-+#define hfc_STATUS_FRAMEINT	  0x40
-+#define hfc_STATUS_ANYINT	  0x80
-+
-+/* bits in CTMT (Write) */
-+#define hfc_CTMT_CLTIMER    0x80
-+#define hfc_CTMT_TIM3_125   0x04
-+#define hfc_CTMT_TIM25      0x10
-+#define hfc_CTMT_TIM50      0x14
-+#define hfc_CTMT_TIM400     0x18
-+#define hfc_CTMT_TIM800     0x1C
-+#define hfc_CTMT_AUTO_TIMER 0x20
-+#define hfc_CTMT_TRANSB2    0x02
-+#define hfc_CTMT_TRANSB1    0x01
-+
-+/* bits in CIRM (Write) */
-+#define hfc_CIRM_AUX_MSK    0x07
-+#define hfc_CIRM_RESET  	  0x08
-+#define hfc_CIRM_B1_REV     0x40
-+#define hfc_CIRM_B2_REV     0x80
-+
-+/* bits in INT_M1 and INT_S1 */
-+#define hfc_INTS_B1TRANS  0x01
-+#define hfc_INTS_B2TRANS  0x02
-+#define hfc_INTS_DTRANS   0x04
-+#define hfc_INTS_B1REC    0x08
-+#define hfc_INTS_B2REC    0x10
-+#define hfc_INTS_DREC     0x20
-+#define hfc_INTS_L1STATE  0x40
-+#define hfc_INTS_TIMER    0x80
-+
-+/* bits in INT_M2 */
-+#define hfc_M2_PROC_TRANS    0x01
-+#define hfc_M2_GCI_I_CHG     0x02
-+#define hfc_M2_GCI_MON_REC   0x04
-+#define hfc_M2_IRQ_ENABLE    0x08
-+#define hfc_M2_PMESEL        0x80
-+
-+/* bits in STATES */
-+#define hfc_STATES_STATE_MASK     0x0F
-+#define hfc_STATES_LOAD_STATE    0x10
-+#define hfc_STATES_ACTIVATE	     0x20
-+#define hfc_STATES_DO_ACTION     0x40
-+#define hfc_STATES_NT_G2_G3      0x80
-+
-+/* bits in HFCD_MST_MODE */
-+#define hfc_MST_MODE_MASTER	     0x01
-+#define hfc_MST_MODE_SLAVE         0x00
-+/* remaining bits are for codecs control */
-+
-+/* bits in HFCD_SCTRL */
-+#define hfc_SCTRL_B1_ENA	     0x01
-+#define hfc_SCTRL_B2_ENA	     0x02
-+#define hfc_SCTRL_MODE_TE        0x00
-+#define hfc_SCTRL_MODE_NT        0x04
-+#define hfc_SCTRL_LOW_PRIO	     0x08
-+#define hfc_SCTRL_SQ_ENA	     0x10
-+#define hfc_SCTRL_TEST	     0x20
-+#define hfc_SCTRL_NONE_CAP	     0x40
-+#define hfc_SCTRL_PWR_DOWN	     0x80
-+
-+/* bits in SCTRL_E  */
-+#define hfc_SCTRL_E_AUTO_AWAKE    0x01
-+#define hfc_SCTRL_E_DBIT_1        0x04
-+#define hfc_SCTRL_E_IGNORE_COL    0x08
-+#define hfc_SCTRL_E_CHG_B1_B2     0x80
-+
-+/* bits in FIFO_EN register */
-+#define hfc_FIFOEN_B1TX   0x01
-+#define hfc_FIFOEN_B1RX   0x02
-+#define hfc_FIFOEN_B2TX   0x04
-+#define hfc_FIFOEN_B2RX   0x08
-+#define hfc_FIFOEN_DTX    0x10
-+#define hfc_FIFOEN_DRX    0x20
-+
-+#define hfc_FIFOEN_B1     (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
-+#define hfc_FIFOEN_B2     (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
-+#define hfc_FIFOEN_D      (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
-+
-+/* bits in the CONNECT register */
-+#define hfc_CONNECT_B1_shift	0
-+#define hfc_CONNECT_B2_shift	3
-+
-+#define	hfc_CONNECT_HFC_from_ST		0x0
-+#define hfc_CONNECT_HFC_from_GCI	0x1
-+#define hfc_CONNECT_ST_from_HFC		0x0
-+#define hfc_CONNECT_ST_from_GCI		0x2
-+#define hfc_CONNECT_GCI_from_HFC	0x0
-+#define	hfc_CONNECT_GCI_from_ST		0x4
-+
-+/* bits in the __SSL and __RSL registers */
-+#define	hfc_SRSL_STIO	0x40
-+#define hfc_SRSL_ENABLE	0x80
-+#define hfc_SRCL_SLOT_MASK	0x1f
-+
-+/* FIFO memory definitions */
-+
-+#define hfc_FMASK	0x000f
-+#define hfc_ZMASK	0x01ff
-+#define hfc_ZMASKB	0x1fff
-+
-+#define hfc_D_FIFO_SIZE	0x0200
-+#define hfc_B_SUB_VAL	0x0200
-+#define hfc_B_FIFO_SIZE	0x1E00
-+#define hfc_MAX_DFRAMES	0x000f
-+
-+#define hfc_FIFO_DTX_Z1	0x2080
-+#define hfc_FIFO_DTX_Z2 0x2082
-+#define hfc_FIFO_DTX_F1	0x20a0
-+#define hfc_FIFO_DTX_F2	0x20a1
-+#define hfc_FIFO_DTX	0x0000
-+#define hfc_FIFO_DTX_ZOFF	0x000
-+
-+#define hfc_FIFO_DRX_Z1	0x6080
-+#define hfc_FIFO_DRX_Z2 0x6082
-+#define hfc_FIFO_DRX_F1	0x60a0
-+#define hfc_FIFO_DRX_F2	0x60a1
-+#define hfc_FIFO_DRX	0x4000
-+#define hfc_FIFO_DRX_ZOFF	0x4000
-+
-+#define hfc_FIFO_B1TX_Z1	0x2000
-+#define hfc_FIFO_B1TX_Z2 	0x2002
-+#define hfc_FIFO_B1RX_Z1	0x6000
-+#define hfc_FIFO_B1RX_Z2 	0x6002
-+
-+#define hfc_FIFO_B1TX_F1	0x2080
-+#define hfc_FIFO_B1TX_F2	0x2081
-+#define hfc_FIFO_B1RX_F1	0x6080
-+#define hfc_FIFO_B1RX_F2	0x6081
-+
-+#define hfc_FIFO_B1RX_ZOFF	0x4000
-+#define hfc_FIFO_B1TX_ZOFF	0x0000
-+
-+#define hfc_FIFO_B2TX_Z1	0x2100
-+#define hfc_FIFO_B2TX_Z2 	0x2102
-+#define hfc_FIFO_B2RX_Z1	0x6100
-+#define hfc_FIFO_B2RX_Z2 	0x6102
-+
-+#define hfc_FIFO_B2TX_F1	0x2180
-+#define hfc_FIFO_B2TX_F2	0x2181
-+#define hfc_FIFO_B2RX_F1	0x6180
-+#define hfc_FIFO_B2RX_F2	0x6181
-+
-+#define hfc_FIFO_B2RX_ZOFF	0x6000
-+#define hfc_FIFO_B2TX_ZOFF	0x2000
-+
-+#define hfc_BTRANS_THRESHOLD 128
-+#define hfc_BTRANS_THRESMASK 0x00
-+
-+/* Structures */
-+
-+typedef struct hfc_regs {
-+    unsigned char fifo_en;
-+    unsigned char ctmt;
-+    unsigned char int_m1;
-+    unsigned char int_m2;
-+    unsigned char sctrl;
-+    unsigned char sctrl_e;
-+    unsigned char sctrl_r;
-+    unsigned char connect;
-+    unsigned char trm;
-+    unsigned char mst_mode;
-+    unsigned char bswapped;
-+    unsigned char nt_mode;
-+    unsigned char int_drec;
-+} hfc_regs;
-+
-+typedef struct hfc_card {
-+    spinlock_t lock;
-+    unsigned int irq;
-+    unsigned int iomem;
-+    int ticks;		
-+    int clicks;		
-+    unsigned char *pci_io;
-+    void *fifomem;		// start of the shared mem
-+    volatile void *fifos;	// 32k aligned mem for the fifos
-+    struct hfc_regs regs;
-+    unsigned int pcibus;
-+    unsigned int pcidevfn;
-+    struct pci_dev *pcidev;
-+    struct zt_hfc *ztdev;
-+    int	drecinframe;
-+    unsigned char drecbuf[hfc_D_FIFO_SIZE];
-+    unsigned char dtransbuf[hfc_D_FIFO_SIZE];
-+    unsigned char brecbuf[2][ZT_CHUNKSIZE];
-+    unsigned char btransbuf[2][ZT_CHUNKSIZE];
-+    unsigned char cardno;
-+    struct hfc_card *next;
-+} hfc_card;
-+
-+typedef struct zt_hfc {
-+    unsigned int usecount;
-+    struct zt_span span;
-+    struct zt_chan chans[3];
-+    struct hfc_card *card;
-+} zt_hfc;
-+
-+/* tune this */
-+#define hfc_BCHAN_BUFFER	8
-+#define hfc_MAX_CARDS		8
-diff -urNad zaptel-1.2.6/zaphfc/zaptel.conf /tmp/dpep.KTFxyR/zaptel-1.2.6/zaphfc/zaptel.conf
---- zaptel-1.2.6/zaphfc/zaptel.conf	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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
-+loadzone=nl
-+defaultzone=nl
-+
-+span=1,1,3,ccs,ami
-+bchan=1-2
-+dchan=3
-diff -urNad zaptel-1.2.6/zaptel.c /tmp/dpep.KTFxyR/zaptel-1.2.6/zaptel.c
---- zaptel-1.2.6/zaptel.c	2005-12-17 04:04:05.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/zaptel.c	2006-06-16 11:44:13.000000000 +0300
+diff -urN zaptel-1.2.5.orig/zaptel.c zaptel-1.2.5/zaptel.c
+--- zaptel-1.2.5.orig/zaptel.c	2005-12-17 03:04:05.000000000 +0100
++++ zaptel-1.2.5/zaptel.c	2006-04-10 10:39:37.000000000 +0200
 @@ -4913,11 +4913,40 @@
  					*(txb++) = fasthdlc_tx_run_nocheck(&ms->txhdlc);
  				}
@@ -6956,9 +122,9 @@
  			} else {
  				/* Not HDLC */
  				memcpy(buf + ms->readidx[ms->inreadbuf], rxb, left);
-diff -urNad zaptel-1.2.6/zaptel.h /tmp/dpep.KTFxyR/zaptel-1.2.6/zaptel.h
---- zaptel-1.2.6/zaptel.h	2005-12-17 04:04:05.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/zaptel.h	2006-06-16 11:44:13.000000000 +0300
+diff -urN zaptel-1.2.5.orig/zaptel.h zaptel-1.2.5/zaptel.h
+--- zaptel-1.2.5.orig/zaptel.h	2005-12-17 03:04:05.000000000 +0100
++++ zaptel-1.2.5/zaptel.h	2006-04-10 10:39:37.000000000 +0200
 @@ -994,6 +994,13 @@
  	int do_ppp_error;
  	struct sk_buff_head ppp_rq;
@@ -6993,9 +159,9 @@
  struct zt_span {
  	spinlock_t lock;
  	void *pvt;			/* Private stuff */
-diff -urNad zaptel-1.2.6/zconfig.h /tmp/dpep.KTFxyR/zaptel-1.2.6/zconfig.h
---- zaptel-1.2.6/zconfig.h	2005-11-29 20:42:08.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/zconfig.h	2006-06-16 11:44:13.000000000 +0300
+diff -urN zaptel-1.2.5.orig/zconfig.h zaptel-1.2.5/zconfig.h
+--- zaptel-1.2.5.orig/zconfig.h	2005-11-29 19:42:08.000000000 +0100
++++ zaptel-1.2.5/zconfig.h	2006-04-10 10:39:37.000000000 +0200
 @@ -152,4 +152,10 @@
   */
  /* #define FXSFLASH */
@@ -7007,1817 +173,9 @@
 +#define CONFIG_ZAPATA_BRI_DCHANS
 +
  #endif
-diff -urNad zaptel-1.2.6/ztgsm/LICENSE /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/LICENSE
---- zaptel-1.2.6/ztgsm/LICENSE	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/Makefile /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/Makefile
---- zaptel-1.2.6/ztgsm/Makefile	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zapata.conf.duoGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zapata.conf.duoGSM
---- zaptel-1.2.6/ztgsm/zapata.conf.duoGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zapata.conf.quadGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zapata.conf.quadGSM
---- zaptel-1.2.6/ztgsm/zapata.conf.quadGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zapata.conf.unoGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zapata.conf.unoGSM
---- zaptel-1.2.6/ztgsm/zapata.conf.unoGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zaptel.conf.duoGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zaptel.conf.duoGSM
---- zaptel-1.2.6/ztgsm/zaptel.conf.duoGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zaptel.conf.quadGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zaptel.conf.quadGSM
---- zaptel-1.2.6/ztgsm/zaptel.conf.quadGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/zaptel.conf.unoGSM /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/zaptel.conf.unoGSM
---- zaptel-1.2.6/ztgsm/zaptel.conf.unoGSM	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/ztgsm.c /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/ztgsm.c
---- zaptel-1.2.6/ztgsm/ztgsm.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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.6/ztgsm/ztgsm.h /tmp/dpep.KTFxyR/zaptel-1.2.6/ztgsm/ztgsm.h
---- zaptel-1.2.6/ztgsm/ztgsm.h	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/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)
-+
-+
-diff -urNad zaptel-1.2.6/ztpty.c /tmp/dpep.KTFxyR/zaptel-1.2.6/ztpty.c
---- zaptel-1.2.6/ztpty.c	1970-01-01 02:00:00.000000000 +0200
-+++ /tmp/dpep.KTFxyR/zaptel-1.2.6/ztpty.c	2006-06-16 11:44:13.000000000 +0300
+diff -urN zaptel-1.2.5.orig/ztpty.c zaptel-1.2.5/ztpty.c
+--- zaptel-1.2.5.orig/ztpty.c	1970-01-01 01:00:00.000000000 +0100
++++ zaptel-1.2.5/ztpty.c	2006-05-09 12:23:57.000000000 +0200
 @@ -0,0 +1,112 @@
 +#include <stdio.h>
 +#include <stdlib.h>

Modified: zaptel/trunk/debian/rules
===================================================================
--- zaptel/trunk/debian/rules	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/debian/rules	2006-06-19 20:27:22 UTC (rev 1918)
@@ -118,6 +118,14 @@
 	dh_install -a debian/genzaptelconf usr/sbin
 	cp debian/$(PREFIX).lintian \
 	  debian/$(PREFIX)/usr/share/lintian/overrides/$(PREFIX)
+ifeq (1,$(USE_BRISTUFF))
+	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
+else
+	mkdir -p $(MOD_EXAMPLES_DIR)/bristuff_stub
+endif
 
 TARPARDIR=debian/tmp
 TARDIR=$(TARPARDIR)/modules/$(PREFIX)
@@ -147,14 +155,6 @@
 	
 	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 ztgsm; do \
-		mkdir -p $(MOD_EXAMPLES_DIR)/$$module; \
-		cp -a $$module/*.conf* $(MOD_EXAMPLES_DIR)/$$module; \
-	done
-else
-	mkdir -p $(MOD_EXAMPLES_DIR)/bristuff_stub
-endif
 	
 	#rm -rf modules
 
@@ -170,7 +170,6 @@
 	
 	dh_installdocs -i
 	dh_installchangelogs -i ChangeLog
-	dh_installexamples -i $(BRISTUFF_EXAMPLES)
 	dh_link -i
 	dh_compress -i
 	dh_fixperms -i
@@ -192,7 +191,7 @@
 	
 	# should be removed, eventually. Still left for compatibility
 	dh_installinit --update-rcd-params="defaults 15 30"
-	dh_installexamples -a zaptel.conf.sample 
+	dh_installexamples -a zaptel.conf.sample $(BRISTUFF_EXAMPLES)
 	
 	dh_installmodules -a
 	dh_installchangelogs -a ChangeLog

Modified: zaptel/trunk/debian/zaptel-source.dirs
===================================================================
--- zaptel/trunk/debian/zaptel-source.dirs	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/debian/zaptel-source.dirs	2006-06-19 20:27:22 UTC (rev 1918)
@@ -1,5 +1,2 @@
-usr/src/modules/zaptel/zaphfc
-usr/src/modules/zaptel/zaphfc-florz
-usr/src/modules/zaptel/qozap
-usr/src/modules/zaptel/debian
+usr/src
 usr/include/linux

Added: zaptel/trunk/qozap/LICENSE
===================================================================
--- zaptel/trunk/qozap/LICENSE	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/LICENSE	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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.

Added: zaptel/trunk/qozap/Makefile
===================================================================
--- zaptel/trunk/qozap/Makefile	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/Makefile	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,91 @@
+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) -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 -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)
+
+OBJS=qozap.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=qozap
+
+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)
+
+qozap.o: qozap.c qozap.h 
+	$(CC) -c qozap.c $(KFLAGS)
+
+clean:	
+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
+	rm -rf .tmp_versions
+
+testlinux24: all
+	modprobe zaptel
+	insmod ./qozap.o
+	ztcfg -v
+	cat /proc/interrupts
+	sleep 1
+	cat /proc/interrupts
+	rmmod qozap zaptel
+
+testlinux26: all
+	modprobe zaptel
+	insmod ./qozap.ko
+	ztcfg -v
+	cat /proc/interrupts
+	sleep 1
+	cat /proc/interrupts
+	rmmod qozap zaptel
+
+reload:	unload load
+load:	load$(BUILDVER)
+
+test:	test$(BUILDVER)
+
+
+loadlinux24: linux24
+	modprobe zaptel
+	insmod ./qozap.o
+	ztcfg -v
+
+loadlinux26: linux26
+	sync
+	modprobe zaptel
+	insmod ./qozap.ko
+	ztcfg -v
+
+unload: 
+	rmmod qozap zaptel
+
+install:	install$(BUILDVER)
+
+installlinux26:
+	install -D -m 644 qozap.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/qozap.ko
+
+installlinux24:
+	install -D -m 644 qozap.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/qozap.o

Added: zaptel/trunk/qozap/TODO
===================================================================
--- zaptel/trunk/qozap/TODO	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/TODO	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,9 @@
+- native-native bridging
+- onchip dtmf
+- E channel support for full debug
+
+
+t3 (5ms max)
+
+t4 (500ms) layer 1 down/up
+

Added: zaptel/trunk/qozap/qozap.c
===================================================================
--- zaptel/trunk/qozap/qozap.c	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/qozap.c	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,1545 @@
+/*
+ * qozap.c - Zaptel driver for the quadBRI PCI ISDN card
+ * and the octoBRI PCI ISDN card!
+ *
+ * Copyright (C) 2003, 2004, 2005 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 "qozap.h"
+
+#if CONFIG_PCI
+
+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;
+static int qoz_dev_count = 0;
+static int totalBRIs = 0;
+static struct pci_dev *multi_qoz = NULL;
+static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
+
+static int ztqoz_shutdown(struct zt_span *span);
+
+int qoz_waitbusy(struct qoz_card *qoztmp) {
+    int x=1000;
+    while (x-- && (qoz_inb(qoztmp,qoz_R_STATUS) & 1));
+    if (x < 0) {
+	return -1;
+    } else {
+	return 0;
+    }
+}
+
+void qoz_shutdownCard(struct qoz_card *qoztmp) {
+    int s=0;
+    unsigned long flags;
+    int stports=0;
+    if (qoztmp == NULL) {
+	printk(KERN_INFO "qozap: shutting down NULL card!\n");
+	return;
+    }
+
+    if ((qoztmp->pci_io == NULL) || (qoztmp->ioport == 0)) {
+	return;
+    }
+
+    if (debug)
+	printk(KERN_INFO "qozap: shutting down card %d (cardID %d) at io port %#x.\n",qoztmp->cardno,qoztmp->cardID,(u_int) qoztmp->ioport);
+
+    if (qoztmp->ztdev != NULL) {
+	stports = qoztmp->stports;
+	for (s=0; s < stports; s++) {
+	    if(qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
+		ztqoz_shutdown(&qoztmp->ztdev->spans[s]);
+		if (debug)
+		    printk(KERN_INFO "qozap: shutdown card %d span %d.\n",qoztmp->cardno,s+1);
+	    }
+	}
+    }
+
+    spin_lock_irqsave(&qoztmp->lock,flags);
+
+    // turn off irqs
+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0); 
+    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
+
+
+    // softreset
+    qoz_outb(qoztmp,qoz_R_CIRM,0x8);
+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
+    qoz_waitbusy(qoztmp);
+
+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0); 
+    qoz_outb(qoztmp,qoz_R_SCI_MSK, 0); 
+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
+
+    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;
+
+    if (qoztmp->pcidev != NULL) {
+        pci_disable_device(qoztmp->pcidev);
+    }
+    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, 0);	
+    
+    free_irq(qoztmp->irq,qoztmp);
+    spin_unlock_irqrestore(&qoztmp->lock,flags);
+
+    if (qoztmp->ztdev != NULL) {
+	stports = qoztmp->stports;
+	for (s=0; s < stports; s++) {
+	    if(qoztmp->ztdev->spans[s].flags & ZT_FLAG_REGISTERED) {
+		zt_unregister(&qoztmp->ztdev->spans[s]);
+		if (debug)
+		    printk(KERN_INFO "qozap: unregistered card %d span %d.\n",qoztmp->cardno,s+1);
+	    }
+	}
+	kfree(qoztmp->ztdev);
+	qoztmp->ztdev = NULL;
+    }
+}
+
+void qoz_doLEDs(struct qoz_card *qoztmp) {
+    unsigned char leds = 0x0;
+    if ((qoztmp->type == 0xb520) && (qoztmp->stports == 4)){
+//	if ((qoztmp->ticks > 0) && (qoztmp->ticks <= 300)) {
+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x20 | 0x10);
+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0xf);
+	    qoz_outb(qoztmp,qoz_R_GPIO_OUT1,(qoztmp->leds[0] | (qoztmp->leds[1] << 1) | (qoztmp->leds[2] << 2) | (qoztmp->leds[3] << 3)));
+/*	}
+	if ((qoztmp->ticks > 300) && (qoztmp->ticks <= 600)) {
+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0x0);
+	} */
+    } else if ((qoztmp->type == 0xb550) && (qoztmp->stports == 4)){
+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x80 | 0x40 | 0x20 | 0x10);
+    	    qoz_outb(qoztmp,qoz_R_GPIO_EN1,0xff);
+	    if (qoztmp->leds[0] == 0) {
+		leds |= 0x80;
+	    } else {
+		leds |= 0x40;
+	    }
+	    if (qoztmp->leds[1] == 0) {
+		leds |= 0x10;
+	    } else {
+		leds |= 0x20;
+	    }
+	    if (qoztmp->leds[2] == 0) {
+		leds |= 0x04;
+	    } else {
+		leds |= 0x08;
+	    }
+	    if (qoztmp->leds[3] == 0) {
+		leds |= 0x02;
+	    } else {
+		leds |= 0x01;
+	    }
+    /* 	0x80 st1g
+	0x40 st1r
+	0x20 st2r
+	0x10 st2g	
+	0x08 st3r
+	0x04 st3g
+	0x02 st4g
+	0x01 st4r
+    */
+	    qoz_outb(qoztmp,qoz_R_GPIO_OUT1, leds);
+    }
+}
+
+void qoz_doWD(struct qoz_card *qoztmp) {
+    if (!qoztmp->wdp) {
+	return;
+    }
+    if (qoztmp->wdp == 1) {
+	    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P2);
+	    qoztmp->wdp = 2;
+    } else {
+	    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P1);
+	    qoztmp->wdp = 1;
+    }
+    qoz_inb_io(qoztmp,qoz_R_CHIP_ID);    
+}
+
+void qoz_undoWD(struct qoz_card *qoztmp) {
+    printk(KERN_INFO "qozap: Stopping hardware watchdog.\n");
+    qoz_outdw_io(qoztmp,0x4000, qoz_WD_P0);
+    qoztmp->wdp = 0;
+    qoz_inb_io(qoztmp,qoz_R_CHIP_ID);    
+}
+
+void qoz_resetCard(struct qoz_card *qoztmp) {
+    unsigned long flags;
+    unsigned char i=0;
+    spin_lock_irqsave(&(qoztmp->lock),flags);
+    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+    
+    // soft reset
+    qoz_outb(qoztmp,qoz_R_CIRM,0x8);
+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
+    qoz_waitbusy(qoztmp);
+
+    // fifo reset
+    qoz_outb(qoztmp,qoz_R_CIRM,0x10);
+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
+    qoz_waitbusy(qoztmp);
+
+    // s/t reset
+    qoz_outb(qoztmp,qoz_R_CIRM,0x40);
+    qoz_outb(qoztmp,qoz_R_CIRM,0x0); 
+    qoz_waitbusy(qoztmp);
+
+    /* set S0 amplitude */
+    qoz_outb(qoztmp,qoz_R_PWM_MD,0xa0);
+    if (qoztmp->type == 0xb552) {
+	qoz_outb(qoztmp,qoz_R_PWM0,0x19);
+    } else {
+	qoz_outb(qoztmp,qoz_R_PWM0,0x1E);
+    }
+
+    /* set up the timer */
+    qoz_outb(qoztmp,qoz_R_TI_WD, 0x2); 
+    qoz_outb(qoztmp,qoz_R_IRQMSK_MISC, 0x2); 
+
+    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); 
+
+    if (qoztmp->type == 0xb552) {
+        qoz_outb(qoztmp,qoz_R_FIFO_MD,0x16);
+    } else {
+        qoz_outb(qoztmp,qoz_R_FIFO_MD,0x26);
+    }
+
+    // double clock
+    if (doubleclock == 1) {
+	// hopefully you have set CLK_MODE correctly!
+	qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
+    } else {
+	if (qoztmp->type == 0x08b4) {
+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x0); 
+	} else if (qoztmp->type == 0xb550) {
+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x23); 
+	} else if (qoztmp->type == 0xb520) {
+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
+	} else {
+	    /* you are on your own here! */
+	    qoz_outb(qoztmp,qoz_R_BRG_PCM_CFG,0x20); 
+	}
+    }
+    qoz_outb(qoztmp,qoz_R_CTRL,0x0); 
+
+    /* R0 G1 */
+    qoztmp->leds[0] = 0x0;
+    qoztmp->leds[1] = 0x0;
+    qoztmp->leds[2] = 0x0;
+    qoztmp->leds[3] = 0x0;
+    qoztmp->leds[4] = 0x0;
+    qoztmp->leds[5] = 0x0;
+    qoztmp->leds[6] = 0x0;
+    qoztmp->leds[7] = 0x0;
+
+    /* Finally enable IRQ output */
+//    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0x8 | 0x1); 
+    if (qoztmp->type == 0xb552) {
+	qoztmp->stports = 8;
+    } else {
+	qoztmp->stports = 4;
+    }
+    qoztmp->ticks = 0;
+    qoztmp->clicks = 0;
+    if (qoztmp->type == 0xb550) {
+	printk(KERN_INFO "qozap: Starting hardware watchdog.\n");
+	qoztmp->wdp = 2;
+    } else {
+	qoztmp->wdp = 0;
+    }
+
+    for (i=0;i<qoztmp->stports;i++) {
+	if (qoztmp->st[i].nt_mode) {
+	    qoz_outb(qoztmp,qoz_R_ST_SYNC,0x8 | i);
+	    if (debug)
+		printk(KERN_INFO "qoztmp: using NT port %d for sync\n", i);
+	    break;
+	}
+    }
+    if (i == qoztmp->stports) {
+	qoz_outb(qoztmp,qoz_R_ST_SYNC,0x0);
+    }
+    spin_unlock_irqrestore(&(qoztmp->lock),flags);
+}
+
+void qoz_registerCard(struct qoz_card *qozcard) {
+    spin_lock(&registerlock);
+    if (qozcard != NULL) {
+	qozcard->prev = NULL;
+	qozcard->next = qoz_dev_list;
+	if (qoz_dev_list) {
+	    qoz_dev_list->prev = qozcard;
+	}
+	qoz_dev_list = qozcard;
+	qozcard->cardno = ++qoz_dev_count;
+    } else {
+	printk(KERN_INFO "qozap: trying to register NULL card.\n");
+    }
+    spin_unlock(&registerlock);
+}
+
+static int qoz_dfifo_tx(struct qoz_card *qoztmp, int stport) {
+    int chan = 2;
+    int x=0;
+    char fifo = 0;
+    char offset = 0;
+
+    if (qoztmp->type == 0xb552) {
+	offset = 24;
+    } else {
+	offset = 28;
+    }
+
+    fifo = stport + offset;
+
+    if (qoztmp->ztdev->chans[stport][chan].bytes2transmit < 1) {
+	return 0;
+    } else {
+	/* select fifo */
+	qoz_outb(qoztmp,qoz_R_FIFO,fifo << 1);    
+	qoz_waitbusy(qoztmp);
+    
+	if (debug > 1)
+	    printk(KERN_INFO "qozap: card %d stport %d TX [ ", qoztmp->cardno, stport + 1);
+	/* copy frame to fifo */
+    	for (x=0;x<qoztmp->ztdev->chans[stport][chan].bytes2transmit;x++) {
+	    if (debug > 1)
+	        printk("%#x ",qoztmp->dtxbuf[stport][x]);
+    	    qoz_outb(qoztmp,qoz_A_FIFO_DATA0,qoztmp->dtxbuf[stport][x]);
+	}
+	if (debug > 1)
+	    printk("] %d bytes\n",qoztmp->ztdev->chans[stport][chan].bytes2transmit);
+
+	if (qoztmp->ztdev->chans[stport][chan].eoftx == 1) {
+	    /* transmit HDLC frame */
+    	    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x1);    
+    	    qoz_waitbusy(qoztmp);
+	}
+    }
+    return 0;
+}
+
+static int qoz_fifo_tx(struct qoz_card *qoztmp, char fifo) {
+    int stport = fifo / 2;
+    int chan = fifo % 2;
+
+    /* select fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,0x80 | (fifo << 1));    
+    qoz_waitbusy(qoztmp);
+    /* transmit 8 bytes of transparent data */
+    qoz_outdw(qoztmp,qoz_A_FIFO_DATA0,*((unsigned int *) &qoztmp->txbuf[stport][chan][0]));
+    qoz_outdw(qoztmp,qoz_A_FIFO_DATA0,*((unsigned int *) &qoztmp->txbuf[stport][chan][4]));
+	    
+    return 0;
+}
+
+static int qoz_dfifo_rx(struct qoz_card *qoztmp, int stport) {
+    unsigned char f1=1,f2=1,data,stat;
+    unsigned char of1=0,of2=0;
+    int len,i;
+    unsigned short z1=1,z2=1;
+    unsigned short oz1=0,oz2=0;
+    char fifo = 0;
+    char offset = 0;
+
+    if (qoztmp->type == 0xb552) {
+	offset = 24;
+    } else {
+	offset = 28;
+    }
+
+    fifo = stport + offset;
+    // select rx fifo
+    
+    qoz_outb(qoztmp,qoz_R_FIFO,(fifo << 1) | 1);    
+    qoz_waitbusy(qoztmp);
+
+    while ((of1 != f1) && (of2 != f2)) {
+        of1 = f1;
+        of2 = f2;
+        f1 = qoz_inb(qoztmp,qoz_A_F1) & 0xf;
+        f2 = qoz_inb(qoztmp,qoz_A_F2) & 0xf;
+    }
+    
+    if (f1 == f2) {
+	/* no frame */
+	qoztmp->st[stport].drx--;
+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
+	return 0;
+    }
+    
+    while ((oz1 != z1) && (oz2 != z2)) {
+        oz1 = z1;
+        oz2 = z2;
+	if (qoztmp->type != 0xb552) {
+    	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x7ff;
+	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x7ff;
+	} else {
+    	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x3ff;
+	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x3ff;
+	}
+    }
+    
+    if (qoztmp->type == 0xb552) {
+	len = z1 - z2;
+	if (len < 0) {
+	    len += qoz_DFIFO_SIZE8;
+	}
+    } else {
+	len = z1 - z2;
+	if (len < 0) {
+	    len += qoz_DFIFO_SIZE4;
+	}
+    }
+
+    if (len > qoz_DFIFO_SIZE4) {
+	printk(KERN_INFO "\nqozap: buffer overflow in D channel RX!\n");
+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
+	qoztmp->ztdev->chans[stport][2].eofrx = 0;
+    } else {
+	if (debug > 1) printk(KERN_INFO "qozap: card %d span %d RX [ ", qoztmp->cardno, stport + 1);
+	for (i=0; i<len; i++) {
+    	    data = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
+	    qoztmp->drxbuf[stport][i] = data;
+	    if (debug > 1) printk("%#x ",data);
+	}
+	if (debug > 1) printk("] %d bytes\n", len);
+	qoztmp->ztdev->chans[stport][2].bytes2receive = i;
+	qoztmp->ztdev->chans[stport][2].eofrx = 1;
+    }
+
+    stat = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
+    if (stat != 0x0) {
+	// bad CRC, skip it
+	printk(KERN_INFO "qozap: CRC error for HDLC frame on card %d (cardID %d) S/T port %d\n",qoztmp->cardno, qoztmp->cardID, stport+1);
+	qoztmp->ztdev->chans[stport][2].bytes2receive = 0;
+	qoztmp->ztdev->chans[stport][2].eofrx = 0;
+//        zt_qevent_nolock(&qoztmp->ztdev->chans[stport][2], ZT_EVENT_BADFCS);
+    }
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x1);    
+    qoz_waitbusy(qoztmp);
+
+    /* frame recevived */
+    if (qoztmp->st[stport].drx > 0) { 
+	qoztmp->st[stport].drx--;
+    } else {
+	printk(KERN_INFO "qozap: trying to receive too much (card %d span %d drx %d)\n", qoztmp->cardno, stport+1, qoztmp->st[stport].drx);
+	qoztmp->st[stport].drx = 0;
+    }
+    return 0;
+}
+
+
+static int qoz_fifo_rx(struct qoz_card *qoztmp, char fifo) {
+    int stport = fifo / 2;
+    int chan = fifo % 2;
+    unsigned char data;
+    int len,i;
+    unsigned short z1=1,z2=1;
+    unsigned short oz1=0,oz2=0;
+    int mumbojumbo=0;
+
+        /* select rx fifo */
+	qoz_outb(qoztmp,qoz_R_FIFO,0x80 | (fifo << 1) | 1);    
+        qoz_waitbusy(qoztmp);
+    
+	while ((oz1 != z1) && (oz2 != z2)) {
+	    oz1 = z1;
+	    oz2 = z2;
+	    z1 = qoz_inw(qoztmp,qoz_A_Z1) & 0x7f;
+    	    z2 = qoz_inw(qoztmp,qoz_A_Z2) & 0x7f;
+	}
+	len = z1 - z2;
+	if (len < 0) {
+	    len += qoz_FIFO_SIZE;
+	}
+	if (len > 2 * ZT_CHUNKSIZE) {
+	    mumbojumbo = len - (2 * ZT_CHUNKSIZE);
+	    len = ZT_CHUNKSIZE;
+	    for (i=0;i<mumbojumbo;i++) {
+    		data = qoz_inb(qoztmp,qoz_A_FIFO_DATA0);
+	    }
+	    qoztmp->clicks++;
+	    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;
+	    }
+	}
+	if (len < ZT_CHUNKSIZE) {
+//	    printk(KERN_INFO "qozap: not enough to receive (%d bytes)\n",len);
+	    return 0;
+	} else {
+	    if (bloop) {
+		*((unsigned int *) &qoztmp->txbuf[stport][chan][0]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
+	        *((unsigned int *) &qoztmp->txbuf[stport][chan][4]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
+	    } else {
+		*((unsigned int *) &qoztmp->rxbuf[stport][chan][0]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
+	        *((unsigned int *) &qoztmp->rxbuf[stport][chan][4]) = qoz_indw(qoztmp,qoz_A_FIFO_DATA0);
+	    }
+	}
+	if (bloop == 0)
+	    zt_ec_chunk(&qoztmp->ztdev->spans[stport].chans[chan], qoztmp->ztdev->spans[stport].chans[chan].readchunk, qoztmp->ztdev->spans[stport].chans[chan].writechunk);
+
+//    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,qoztmp->st[stport].dbufi,f1,f2,z1,z2,len,stat,hdlc);    
+    return 0;
+}
+
+
+static inline void qoz_run(struct qoz_card *qoztmp) {
+    int s=0;
+    if (qoztmp->ztdev != NULL) {
+	for (s=0;s<qoztmp->stports;s++) {
+	if (!bloop) {
+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
+		/* oh zaptel! tell us what to transmit... */
+    		zt_transmit(&qoztmp->ztdev->spans[s]);
+	        /* B1 xmit */
+		qoz_fifo_tx(qoztmp, s * 2);
+		/* B2 xmit */
+		qoz_fifo_tx(qoztmp, (s * 2) + 1);
+
+		if ((qoztmp->st[s].layer1state != 7) && (qoztmp->ztdev->chans[s][2].bytes2transmit > 0) && (qoztmp->st[s].nt_mode != 1)) {
+		    if (qoztmp->st[s].t3 == -1) {
+			printk(KERN_INFO "qozap: activating layer 1, span %d\n",s);
+			qoztmp->st[s].t3 = 0;
+			qoz_outb(qoztmp,qoz_R_ST_SEL, s);
+			qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60); 
+		    } else {
+		    }
+		}
+		
+		/* D xmit */
+		if (qoztmp->ztdev->spans[s].alarms != ZT_ALARM_RED) {
+		    qoz_dfifo_tx(qoztmp, s);
+		} else {
+		    if ((qoztmp->st[s].t3 == -1) && (qoztmp->st[s].t4 == -1) && (qoztmp->st[s].layer1state == 3) && (qoztmp->st[s].nt_mode != 1)) {
+			/* clear alarms */
+			printk(KERN_INFO "qozap: clearing alarms on span %d\n",s);
+			qoztmp->ztdev->spans[s].alarms = ZT_ALARM_NONE;
+			zt_alarm_notify(&qoztmp->ztdev->spans[s]);
+		    }
+		}
+
+		qoztmp->ztdev->chans[s][2].bytes2receive = 0;
+		qoztmp->ztdev->chans[s][2].bytes2transmit = 0;
+		qoztmp->ztdev->chans[s][2].eofrx = 0;
+		qoztmp->ztdev->chans[s][2].eoftx = 0;
+
+	    }
+
+	    /* B1 receive */
+	    qoz_fifo_rx(qoztmp,(s*2));
+	    /* B2 receive */
+	    qoz_fifo_rx(qoztmp,(s*2)+1);
+	    /* d-chan data */
+	    if (qoztmp->st[s].drx > 0) {
+	        if (debug > 2)
+		    printk(KERN_CRIT "qozap: card %d st[%d].drx = %d\n", qoztmp->cardno, s, qoztmp->st[s].drx);
+		qoz_dfifo_rx(qoztmp, s);
+	    }
+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
+	        /* oh zaptel! thou shall receive! */
+		zt_receive(&(qoztmp->ztdev->spans[s]));
+	    }
+	} else {
+	    // loop
+	    /* B1 receive */
+	    qoz_fifo_rx(qoztmp,(s*2));
+	    /* B2 receive */
+	    qoz_fifo_rx(qoztmp,(s*2)+1);
+	    /* d-chan data */
+/*	    if (qoztmp->st[s].drx > 0) {
+	        if (debug > 2)
+		    printk(KERN_CRIT "qozap: card %d st[%d].drx = %d\n", qoztmp->cardno, s, qoztmp->st[s].drx);
+		qoz_dfifo_rx(qoztmp, s);
+	    } 
+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
+		zt_receive(&(qoztmp->ztdev->spans[s]));
+	    }
+*/
+	    if (qoztmp->ztdev->spans[s].flags & ZT_FLAG_RUNNING) {
+		/* oh zaptel! tell us what to transmit... */
+    	//	zt_transmit(&qoztmp->ztdev->spans[s]);
+	        /* B1 xmit */
+		qoz_fifo_tx(qoztmp, s * 2);
+		/* B2 xmit */
+		qoz_fifo_tx(qoztmp, (s * 2) + 1);
+		/* D xmit */
+//		qoz_dfifo_tx(qoztmp, s);
+
+		qoztmp->ztdev->chans[s][2].bytes2receive = 0;
+		qoztmp->ztdev->chans[s][2].bytes2transmit = 0;
+		qoztmp->ztdev->chans[s][2].eofrx = 0;
+		qoztmp->ztdev->chans[s][2].eoftx = 0;
+
+	    }
+	}
+	} 
+    }
+}
+
+#ifdef LINUX26
+static irqreturn_t qoz_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
+#else
+static void qoz_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
+#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;
+
+    if (!qoztmp) {
+#ifdef LINUX26
+		return IRQ_NONE;
+#else
+		return;
+#endif		
+    }
+
+    if ((!qoztmp->pci_io) || (!qoztmp->ioport)) {
+	    printk(KERN_CRIT "qozap: no pci mem/io\n");
+#ifdef LINUX26
+		return IRQ_NONE;
+#else
+		return;
+#endif		
+    }
+    if (qoztmp->dead) {
+#ifdef LINUX26
+	return IRQ_RETVAL(1);
+#else
+	return;
+#endif		
+    }
+
+    
+#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!
+#ifdef RELAXED_LOCKING
+	spin_unlock(&(qoztmp->lock));
+#else
+	spin_unlock_irqrestore(&(qoztmp->lock), flags);
+#endif
+#ifdef LINUX26
+		return IRQ_NONE;
+#else
+		return;
+#endif		
+    }
+    /* state machine irq */
+    if (irq_sci != 0) {
+	if (debug > 1) {
+	    printk(KERN_INFO "R_BERT_STA = %#x\n", qoz_inb(qoztmp, qoz_R_BERT_STA) & 7);
+	}
+	for (st=0;st<qoztmp->stports;st++) {
+	    if (irq_sci & (1 << st)) {
+		qoz_outb(qoztmp,qoz_R_ST_SEL,st);
+		l1state = qoz_inb(qoztmp,qoz_A_ST_RD_STA) & 0xf;
+		if (debug > 1) {
+		    printk(KERN_INFO "A_ST_RD_STA = %#x\n", qoz_inb(qoztmp, qoz_A_ST_RD_STA));
+		}
+		qoztmp->st[st].layer1state = l1state;
+		if (qoztmp->st[st].nt_mode == 1) {
+		    if (debug)
+			printk(KERN_INFO "card %d span %d state G%d (A_ST_RD_STA = %#x)\n",qoztmp->cardno,st+1,l1state,qoz_inb(qoztmp,qoz_A_ST_RD_STA));
+		    // NT state machine
+		    if (l1state == 3) {
+			// keep layer1 up!
+			if (qoztmp->stports == 8) {
+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [NT] Layer 1 ACTIVATED (G%d)",qoztmp->cardno ,st + 1, l1state);
+			} else {
+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d) Layer 1 ACTIVATED (G%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
+			}
+			qoz_outb(qoztmp,qoz_A_ST_WR_STA,3 | 0x10 );
+			qoztmp->leds[st] = 1;
+		    } else {
+			if (qoztmp->stports == 8) {
+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [NT] Layer 1 DEACTIVATED (G%d)",qoztmp->cardno ,st + 1, l1state);
+			} else {
+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d) Layer 1 DEACTIVATED (G%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
+			}
+			qoztmp->leds[st] = 0;
+		    }
+		} else {
+		    if (debug)
+			printk(KERN_INFO "card %d span %d state F%d (A_ST_RD_STA = %#x)\n",qoztmp->cardno,st+1,l1state,qoz_inb(qoztmp,qoz_A_ST_RD_STA));
+		    // TE state machine
+		    if (l1state == 3) {
+			if (qoztmp->st[st].t3 > -1)  {
+			    /* keep layer1 up, if the span is started. */
+			    if (qoztmp->ztdev->spans[st].flags & ZT_FLAG_RUNNING) {
+printk("qozap: re-activating layer1 span %d\n", st);
+    				qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60);
+			    }
+			} else {
+printk("qozap: not re-activating layer1 span %d\n", st);
+    				qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x40);
+			    /* if we tried to activate layer 1 and it failed make this an alarm */
+//			    qoztmp->ztdev->spans[st].alarms = ZT_ALARM_RED;
+//			    zt_alarm_notify(&qoztmp->ztdev->spans[st]);
+			    /* if the network shuts us down in idle mode dont make this an alarm */
+			}
+			qoztmp->leds[st] = 0;
+			if (qoztmp->stports == 8) {
+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
+			} else {
+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
+			}
+		    } else if (l1state == 7) {
+			/* activation complete, stop timer t3 */
+			qoztmp->st[st].t3 = -1;
+			qoztmp->ztdev->spans[st].alarms = ZT_ALARM_NONE;
+			zt_alarm_notify(&qoztmp->ztdev->spans[st]);
+			qoztmp->leds[st] = 1;
+			if (qoztmp->stports == 8) {
+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 ACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
+			} else {
+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 ACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
+			}
+		    } else if (l1state == 8) {
+			/* lost framing */
+			printk(KERN_INFO "qozap: starting t4 for span %d\n", st);
+			qoztmp->st[st].t4 = 0;
+		    } else {
+			if (qoztmp->stports == 8) {
+			    sprintf(ztqoz->spans[st].desc,"octoBRI PCI ISDN Card %d Span %d [TE] Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1, l1state);
+			} else {
+			    sprintf(ztqoz->spans[st].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d) Layer 1 DEACTIVATED (F%d)",qoztmp->cardno ,st + 1,ztqoz->card->cardID, l1state);
+			}    
+		    }
+		}
+		
+	    }
+	}
+    }
+
+
+    // misc irq
+    if (status & 0x40) {
+	irq_misc = qoz_inb(qoztmp,qoz_R_IRQ_MISC);
+	if (irq_misc & 0x2)  {
+	    // qozap timer
+	    qoztmp->ticks++;
+	    qoz_run(qoztmp);
+	    if (qoztmp->ticks % 100) {
+		qoz_doLEDs(qoztmp);
+	    }
+    	    if (qoztmp->ticks % 40) { 
+		/* you thought that 42 was the answer.... */
+		qoz_doWD(qoztmp);
+	    }
+	    if (qoztmp->ticks > 1000) {
+		qoztmp->ticks = 0;
+		for (j=0;j<qoztmp->stports;j++) {
+		    /* t3 */
+		    if (qoztmp->st[j].t3 >= 0) {
+			qoztmp->st[j].t3++;
+		    }
+		    if (qoztmp->st[j].nt_mode != 1) {
+			if ((qoztmp->st[j].t3 > qoz_T3) && (qoztmp->st[j].layer1state != 7)) {
+			    /* deactivate layer 1 */
+			    printk(KERN_INFO "qozap: t3 timer expired for span %d\n", j);
+			    qoz_outb(qoztmp,qoz_R_ST_SEL, j);
+			    qoz_outb(qoztmp,qoz_A_ST_WR_STA, 0x40 );
+			    qoztmp->st[j].t3 = -1;
+			    qoztmp->ztdev->spans[j].alarms = ZT_ALARM_RED;
+			    zt_alarm_notify(&qoztmp->ztdev->spans[j]);
+			    qoz_waitbusy(qoztmp);
+			}
+		    }
+		    /* t4 */
+		    if (qoztmp->st[j].t4 >= 0) {
+			qoztmp->st[j].t4++;
+		    }
+		    if (qoztmp->st[j].nt_mode != 1) {
+			if ((qoztmp->st[j].t4 > qoz_T4) && (qoztmp->st[j].layer1state != 7)) {
+			    /* deactivate layer 1 */
+			    printk(KERN_INFO "qozap: t4 timer expired for span %d\n", j);
+			    qoz_outb(qoztmp,qoz_R_ST_SEL, j);
+			    qoz_outb(qoztmp,qoz_A_ST_WR_STA, 0x40 );
+			    qoztmp->st[j].t4 = -1;
+			    qoztmp->ztdev->spans[j].alarms = ZT_ALARM_RED;
+			    zt_alarm_notify(&qoztmp->ztdev->spans[j]);
+			    qoz_waitbusy(qoztmp);
+			}
+		    }
+		}
+	    }
+	}
+	if (irq_misc & 0x4) {
+	//    printk(KERN_INFO "qozap proc/nonproc irq\n");
+	}
+    }
+    if (status & 0x80) {
+	/* fifo irq */
+	irq_foview = qoz_inb(qoztmp,qoz_R_IRQ_OVIEW);
+        if (qoztmp->type == 0xb552) {
+	    if (irq_foview & 0x60) {
+		offset = 0;
+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL6);
+		for (i=0; i < 8; i++) {
+		    if (fi & (1 << i)) {
+			st = offset + (i / 2);
+			if (i % 2) {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
+				qoztmp->st[st].drx += 1;			
+			} else {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
+			}
+		    }
+		}
+	    }
+	    if (irq_foview & 0x80) {
+		offset = 4;
+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL7);
+		for (i=0; i < 8; i++) {
+		    if (fi & (1 << i)) {
+			st = offset + (i / 2);
+			if (i % 2) {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
+				qoztmp->st[st].drx += 1;			
+			} else {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
+			}
+		    }
+		}
+	    }
+	} else {
+	    if (irq_foview & 0x80) {
+		fi = qoz_inb(qoztmp,qoz_R_IRQ_FIFO_BL7);
+		for (i=0; i < 8; i++) {
+		    if (fi & (1 << i)) {
+			st = i / 2;
+			if (i % 2) {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC RX irq fifo %d span %d\n", i, st+1);
+				qoztmp->st[st].drx += 1;			
+			} else {
+			    if (debug > 2) 
+		    		printk(KERN_CRIT "qozap: HDLC TX irq fifo %d span %d\n", i, st+1);
+			}
+		    }
+		}
+	    }
+	}
+    }
+    
+#ifdef RELAXED_LOCKING
+    spin_unlock(&(qoztmp->lock));
+#else
+    spin_unlock_irqrestore(&(qoztmp->lock), flags);
+#endif
+#ifdef LINUX26
+	return IRQ_RETVAL(1);
+#endif		
+}
+
+static int ztqoz_open(struct zt_chan *chan) {
+//    printk(KERN_INFO "qozap: channel %d opened.\n",chan->channo);
+#ifndef LINUX26
+    MOD_INC_USE_COUNT;
+#else
+    try_module_get(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int ztqoz_close(struct zt_chan *chan) {
+//    printk(KERN_INFO "qozap: channel %d closed.\n",chan->channo);
+#ifndef LINUX26
+    MOD_DEC_USE_COUNT;
+#else
+    module_put(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int ztqoz_rbsbits(struct zt_chan *chan, int bits) {
+    return 0;
+}
+
+static int ztqoz_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
+        switch(cmd) {
+        default:
+                return -ENOTTY;
+        }
+        return 0;
+}
+
+static int ztqoz_startup(struct zt_span *span) {
+    struct zt_qoz *qozt = span->pvt;
+    struct qoz_card *qoztmp = qozt->card;
+    unsigned long flags;
+    int alreadyrunning;
+    int i=0;
+    int offset = 0;
+    
+    if (qoztmp == NULL) {
+	printk(KERN_INFO "qozap: no card for span at startup!\n");
+    }
+    
+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+//    printk(KERN_CRIT "already running %d flags %d\n", alreadyrunning, span->flags);
+
+    if (!alreadyrunning) {
+	span->chans[2].flags &= ~ZT_FLAG_HDLC;
+	span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
+    
+	/* setup B channel buffers (8 bytes each) */
+	for (i=0; i<2 ; i++) {
+	    memset(qoztmp->rxbuf[span->offset][i],0x0,sizeof(qoztmp->rxbuf[span->offset][i]));
+    	    span->chans[i].readchunk = qoztmp->rxbuf[span->offset][i];
+    	    memset(qoztmp->txbuf[span->offset][i],0x0,sizeof(qoztmp->txbuf[span->offset][i]));
+	    span->chans[i].writechunk = qoztmp->txbuf[span->offset][i];
+	}
+	/* setup D channel buffer */
+    	memset(qoztmp->dtxbuf[span->offset],0x0,sizeof(qoztmp->dtxbuf[span->offset]));
+	span->chans[2].writechunk = qoztmp->dtxbuf[span->offset];
+	qoztmp->ztdev->chans[span->offset][2].maxbytes2transmit = sizeof(qoztmp->dtxbuf[span->offset]);
+
+	memset(qoztmp->drxbuf[span->offset],0x0,sizeof(qoztmp->drxbuf[span->offset]));
+    	span->chans[2].readchunk = qoztmp->drxbuf[span->offset];
+
+	span->flags |= ZT_FLAG_RUNNING;
+    } else {
+//	printk(KERN_CRIT "already running\n");
+	return 0;
+    }
+
+    spin_lock_irqsave(&qoztmp->lock,flags);
+    // irqs off
+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
+
+    if (qoztmp->type == 0xb552) {
+	offset = 24;
+    } else {
+	offset = 28;
+    }
+
+    /* setup D-FIFO TX */
+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset + offset) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0xD);
+    qoz_outb(qoztmp,qoz_A_SUBCH_CFG,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) + 2) << 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    /* setup D-FIFO RX */
+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset + offset) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0xD);
+    qoz_outb(qoztmp,qoz_A_SUBCH_CFG,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,(((span->offset * 4) + 2) << 1) | 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    /* setup B1-FIFO TX */
+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset * 2) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,(span->offset * 4) << 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    /* setup B1-FIFO RX */
+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) << 1) | 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    /* setup B2-FIFO TX */
+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) + 1) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,((span->offset * 4) + 1) << 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    /* setup B2-FIFO RX */
+    qoz_outb(qoztmp,qoz_R_FIFO,(((span->offset * 2) + 1) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_R_INC_RES_FIFO,0x2);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_CHANNEL,((((span->offset) * 4) + 1) << 1) | 1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x1);
+
+    if (debug)
+        printk(KERN_INFO "qozap: starting card %d span %d/%d.\n",qoztmp->cardno,span->spanno,span->offset);
+    
+    /* activate layer 1 */
+    qoz_outb(qoztmp,qoz_R_ST_SEL,span->offset);
+    if (qoztmp->st[span->offset].nt_mode == 1) {
+	// NT mode
+	qoz_outb(qoztmp,qoz_A_ST_CTRL0,0x7);
+	qoz_outb(qoztmp,qoz_A_ST_CTRL1,0x0);
+	qoz_outb(qoztmp,qoz_A_ST_CTRL2,0x3);
+	qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,0x60 | CLKDEL_NT);
+    } else {
+	// TE mode
+	qoz_outb(qoztmp,qoz_A_ST_CTRL0,0x3);
+	qoz_outb(qoztmp,qoz_A_ST_CTRL1,0x0);
+	qoz_outb(qoztmp,qoz_A_ST_CTRL2,0x3);
+	if (qoztmp->type == 0xb550) {
+	    qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,CLKDEL_TE);
+	} else {
+	    qoz_outb(qoztmp,qoz_A_ST_CLK_DLY,CLKDEL_TE + 1);
+	}
+    }
+    qoztmp->st[span->offset].t3 = 0;
+    qoztmp->st[span->offset].t4 = -1;
+    
+    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,0x80); 
+    } else {
+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x0); 
+    }
+    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
+    } else {
+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x60); // start Activation
+    }
+
+    /* enable irqs */
+    qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 8 | 1); 
+    return 0;
+}
+
+static int ztqoz_shutdown(struct zt_span *span) {
+    struct zt_qoz *ztqoz = span->pvt;
+    struct qoz_card *qoztmp = ztqoz->card;
+    int alreadyrunning;
+    int offset = 0;
+    
+    if (qoztmp == NULL) {
+	printk(KERN_CRIT "qozap: qoztmp == NULL!\n");
+	return 0;
+	
+    }
+
+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+    
+    if (!alreadyrunning) {
+	return 0;
+    }
+
+//    printk(KERN_CRIT "qozap: stopping card %d port %d.\n",qoztmp->cardno, span->offset + 1);
+
+    // turn off irqs for all fifos
+    if (qoztmp->type == 0xb552) {
+	offset = 24;
+    } else {
+	offset = 28;
+    }
+
+    /* disable D TX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset + offset) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
+
+    /* disable D RX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset + offset) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x1);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
+
+    /* disable B1 TX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,(span->offset * 2) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
+
+    /* disable B1 RX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,((span->offset * 2) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
+
+    /* disable B2 TX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,(((span->offset) * 2) + 1) << 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0);
+
+    /* disable B2 RX fifo */
+    qoz_outb(qoztmp,qoz_R_FIFO,((((span->offset) * 2) + 1) << 1) | 1);
+    qoz_waitbusy(qoztmp);
+    qoz_outb(qoztmp,qoz_A_CON_HDLC,0x2);
+    qoz_outb(qoztmp,qoz_A_IRQ_MSK,0x0); 
+
+    span->flags &= ~ZT_FLAG_RUNNING;
+
+    /* Deactivate Layer 1 */
+    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,0x40); 
+    } else {
+	qoz_outb(qoztmp,qoz_A_ST_WR_STA,0x40);
+    }
+
+
+//    printk(KERN_CRIT "qozap: card %d span %d/%d down.\n",qoztmp->cardno,span->spanno,span->offset);
+    return 0;
+}
+
+static int ztqoz_maint(struct zt_span *span, int cmd) {
+    return 0;
+}
+
+static int ztqoz_chanconfig(struct zt_chan *chan,int sigtype) {
+//    printk(KERN_INFO "chan_config sigtype=%d\n",sigtype);
+    return 0;
+}
+
+static int ztqoz_spanconfig(struct zt_span *span,struct zt_lineconfig *lc) {
+//    span->lineconfig = lc->lineconfig;
+    return 0;
+}
+
+static int ztqoz_initialize(struct zt_qoz *ztqoz) {
+    struct qoz_card *qoztmp = ztqoz->card;
+    int i=0,s=0;
+    
+    for (s=0; s < ztqoz->card->stports; s++) {
+	memset(&ztqoz->spans[s],0,sizeof(struct zt_span)); // you never can tell...
+	sprintf(ztqoz->spans[s].name,"ztqoz/%d/%d",qoz_dev_count + 1,s + 1);
+	if (ztqoz->card->stports == 8) {
+	    if (qoztmp->st[s].nt_mode == 1){
+		sprintf(ztqoz->spans[s].desc,"octoBRI PCI ISDN Card %d Span %d [NT]",qoztmp->cardno,s + 1);
+	    } else {
+		sprintf(ztqoz->spans[s].desc,"octoBRI PCI ISDN Card %d Span %d [TE]",qoztmp->cardno,s + 1);
+	    }
+	} else {
+	    if (ztqoz->card->cardID < 0xff) {
+		if (qoztmp->st[s].nt_mode == 1){
+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [NT] (cardID %d)",qoztmp->cardno,s + 1,ztqoz->card->cardID);
+		} else {
+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [TE] (cardID %d)",qoztmp->cardno,s + 1,ztqoz->card->cardID);
+		}
+	    } else {
+		if (qoztmp->st[s].nt_mode == 1){
+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [NT]",qoztmp->cardno,s + 1);
+		} else {
+		    sprintf(ztqoz->spans[s].desc,"quadBRI PCI ISDN Card %d Span %d [TE]",qoztmp->cardno,s + 1);
+		}
+	    }
+	}
+
+        ztqoz->spans[s].spanconfig = ztqoz_spanconfig;
+        ztqoz->spans[s].chanconfig = ztqoz_chanconfig;
+        ztqoz->spans[s].startup = ztqoz_startup;
+        ztqoz->spans[s].shutdown = ztqoz_shutdown;
+        ztqoz->spans[s].maint = ztqoz_maint;
+        ztqoz->spans[s].rbsbits = ztqoz_rbsbits;
+        ztqoz->spans[s].open = ztqoz_open;
+        ztqoz->spans[s].close = ztqoz_close;
+        ztqoz->spans[s].ioctl = ztqoz_ioctl;
+
+        ztqoz->spans[s].chans = ztqoz->chans[s];
+        ztqoz->spans[s].channels = 3;
+        ztqoz->spans[s].deflaw = ZT_LAW_ALAW;
+        ztqoz->spans[s].linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS; // <--- this is really BS
+        init_waitqueue_head(&ztqoz->spans[s].maintq);
+        ztqoz->spans[s].pvt = ztqoz;
+        ztqoz->spans[s].offset = s;
+
+	for (i=0; i < ztqoz->spans[s].channels; i++) {
+	    memset(&(ztqoz->chans[s][i]),0x0,sizeof(struct zt_chan));
+	    sprintf(ztqoz->chans[s][i].name,"ztqoz%d/%d/%d",qoz_dev_count + 1,s + 1,i + 1);
+	    ztqoz->chans[s][i].pvt = ztqoz;
+	    ztqoz->chans[s][i].sigcap =  ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_SF;
+	    ztqoz->chans[s][i].chanpos = i + 1; 
+	}
+
+	if (zt_register(&ztqoz->spans[s],0)) {
+	    printk(KERN_INFO "qozap: unable to register zaptel span %d!\n",s+1);
+	    return -1;
+	}
+//	 printk(KERN_INFO "qozap: registered zaptel span %d.\n",s+1);
+    }
+
+    return 0;
+}
+
+int qoz_findCards(unsigned int pcidid) {
+    struct pci_dev *tmp;
+    struct qoz_card *qoztmp = NULL;
+    struct zt_qoz *ztqoz = NULL;
+    int i=0;
+    unsigned char dips=0;
+    int cid=0;
+    int modes=0;
+    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
+    while (tmp != NULL) {
+	multi_qoz = tmp;	// skip this next time.
+
+	if (pci_enable_device(tmp)) {
+	    multi_qoz = NULL;
+	    return -1;
+	}
+
+	qoztmp = kmalloc(sizeof(struct qoz_card),GFP_KERNEL);
+	if (!qoztmp) {
+	    printk(KERN_WARNING "qozap: unable to kmalloc!\n");
+	    pci_disable_device(tmp);
+	    multi_qoz = NULL;
+	    return -ENOMEM;
+	}
+	memset(qoztmp, 0x0, sizeof(struct qoz_card));
+	
+	spin_lock_init(&qoztmp->lock);
+	qoztmp->pcidev = tmp;
+	qoztmp->pcibus = tmp->bus->number;
+	qoztmp->pcidevfn = tmp->devfn; 
+
+	if (!tmp->irq) {
+	    printk(KERN_WARNING "qozap: no irq!\n");
+	} else {
+	    qoztmp->irq = tmp->irq;
+	}
+
+	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;
+	    return -EIO;
+	}
+
+	qoztmp->ioport = tmp->resource[0].start;
+	if (!qoztmp->ioport) {
+	    printk(KERN_WARNING "qozap: no ioport!\n");
+	    pci_disable_device(tmp);
+	    multi_qoz = NULL;
+	    return -EIO;
+	}
+	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");
+	    kfree(qoztmp);
+	    pci_disable_device(tmp);
+	    multi_qoz = NULL;
+	    return -EIO;
+	}
+
+	qoztmp->pci_io = ioremap((ulong) qoztmp->pci_io_phys, 256);
+	
+	pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+	// disable ints
+	qoz_outb(qoztmp,qoz_R_IRQ_CTRL, 0); 
+
+	ztqoz = kmalloc(sizeof(struct zt_qoz),GFP_KERNEL);
+	if (!ztqoz) {
+	    printk(KERN_INFO "qozap: unable to kmalloc!\n");
+	    qoz_shutdownCard(qoztmp);
+	    kfree(qoztmp);
+	    multi_qoz = NULL;
+	    return -ENOMEM;
+	}
+	memset(ztqoz, 0x0, sizeof(struct zt_qoz));
+
+	if (pcidid == PCI_DEVICE_ID_CCD_M) {
+	    qoztmp->stports = 8;
+	} else {
+	    qoztmp->stports = 4;
+	}
+	
+
+        if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
+	//    printk(KERN_INFO "MODES = %#x.\n",modes);
+	    qoz_outb(qoztmp,qoz_R_GPIO_SEL,0x80 | 0x40);
+	    dips = (qoz_inb(qoztmp,qoz_R_GPIO_IN1) >> 5);
+	    cid = 7;
+	    for (i=0;i<3;i++) {
+	        if ((dips & (1 << i)) != 0) {
+	    	cid -= (1 << (2-i));
+	        }
+	    }
+	//	printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
+        } else if ((tmp->subsystem_device==0xb550) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
+	//    printk(KERN_INFO "MODES = %#x.\n",modes);
+	    dips = ~(qoz_inb(qoztmp,qoz_R_GPI_IN3) & 7);
+	    cid = 0;
+	    for (i=0;i<3;i++) {
+	        if ((dips & (1 << i)) != 0) {
+	    	cid += (1 << i);
+	        }
+	    }
+	printk(KERN_INFO "DIPS = %#x CID= %#x\n",dips,cid);
+        } else {
+	    cid = 0xff;
+        }
+
+	if (ports == -1) {
+    	    if ((tmp->subsystem_device==0xb520) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
+		modes = qoz_inb(qoztmp,qoz_R_GPI_IN3) >> 4;
+    	    } else if ((tmp->subsystem_device==0xb550) && (pcidid == PCI_DEVICE_ID_CCD_M4)) {
+		qoz_outb(qoztmp,qoz_R_GPIO_SEL,0xff);
+		qoz_outb(qoztmp,qoz_R_GPIO_EN0,0x00);
+		printk(KERN_CRIT "gpio_in0 %#x \n", qoz_inb(qoztmp,qoz_R_GPIO_IN0));
+		printk(KERN_CRIT "gpio_in1 %#x \n", qoz_inb(qoztmp,qoz_R_GPIO_IN1));
+		printk(KERN_CRIT "gpi_in1 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN1));
+		printk(KERN_CRIT "gpi_in2 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN2));
+		printk(KERN_CRIT "gpi_in3 %#x \n", qoz_inb(qoztmp,qoz_R_GPI_IN3));
+		modes = qoz_inb(qoztmp,qoz_R_GPI_IN3) >> 4;	    
+	    } else {
+		modes = 0; // assume TE mode
+	    }
+	} else {
+	    modes = ports >> totalBRIs;
+	}
+
+	if (pcidid == PCI_DEVICE_ID_CCD_M4) {
+	    switch (tmp->subsystem_device) {
+		case 0x08b4:
+			if (ports == -1) ports = 0; /* assume TE mode if no ports param */
+			printk(KERN_INFO
+		        "qozap: CologneChip HFC-4S evaluation board configured at io port %#x IRQ %d HZ %d\n",
+		          (u_int) qoztmp->ioport,
+		        qoztmp->irq, HZ);
+		    break;
+		case 0xb520:
+			printk(KERN_INFO
+		        "qozap: Junghanns.NET quadBRI card configured at io port %#x IRQ %d HZ %d CardID %d\n",
+		          (u_int) qoztmp->ioport,
+		        qoztmp->irq, HZ, cid);
+		    break;
+		case 0xb550:
+			printk(KERN_INFO
+		        "qozap: Junghanns.NET quadBRI (Version 2.0) card configured at io port %#x IRQ %d HZ %d CardID %d\n",
+		          (u_int) qoztmp->ioport,
+		        qoztmp->irq, HZ, cid);
+		    break;
+	    } 
+	    totalBRIs += 4;
+	} else {
+	    switch (tmp->subsystem_device) {
+		case 0xb552:
+		    printk(KERN_INFO
+		       "qozap: Junghanns.NET octoBRI card configured at io port %#x IRQ %d HZ %d\n",
+		       (u_int) qoztmp->ioport,
+		       qoztmp->irq, HZ);
+	        break;
+		default:
+		    printk(KERN_INFO
+		       "qozap: wtf\n");
+		    if (qoztmp->pcidev != NULL) {
+    			pci_disable_device(qoztmp->pcidev);
+		    }
+		    pci_write_config_word(qoztmp->pcidev, PCI_COMMAND, 0);	
+		    free_irq(qoztmp->irq,qoztmp);
+		    kfree(qoztmp);
+		    qoztmp = NULL;
+		    tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
+		    continue;
+		break;		
+	    } 
+	    totalBRIs += 8;
+	}
+
+	qoztmp->cardID = cid;
+	qoztmp->type = tmp->subsystem_device;
+
+	printk(KERN_INFO "qozap: S/T ports: %d [",qoztmp->stports);
+	for (i=0;i<qoztmp->stports;i++) {
+	    if ((modes & (1 << i)) != 0) {
+	        qoztmp->st[i].nt_mode = 1;
+	        printk(" NT");
+	    } else {
+	        qoztmp->st[i].nt_mode = 0;
+	        printk(" TE");
+	    }
+	}
+	printk(" ]\n");
+	
+	ztqoz->card = qoztmp;
+	qoztmp->ztdev = ztqoz;
+
+	qoz_registerCard(qoztmp);
+	tmp = pci_find_device(PCI_VENDOR_ID_CCD,pcidid,multi_qoz);
+    }
+    return 0;
+}
+
+
+int qoz_sortCards(void) {
+    int changed=0,tmpcardno;
+    struct qoz_card *tmpcard,*tmpcard2;
+    spin_lock(&registerlock);
+    do {
+	changed = 0;
+	tmpcard = qoz_dev_list;
+	while (tmpcard != NULL) {
+	    if (tmpcard->prev) {
+		if (tmpcard->prev->cardID > tmpcard->cardID) {
+		    tmpcardno = tmpcard->prev->cardno;
+		    tmpcard->prev->cardno = tmpcard->cardno; 
+		    tmpcard->cardno = tmpcardno;
+		
+		    tmpcard2 = tmpcard->prev;
+		    if (tmpcard2->prev) {
+			tmpcard2->prev->next = tmpcard;
+		    } else {
+			qoz_dev_list = tmpcard;
+		    }
+		    if (tmpcard->next) {
+			tmpcard->next->prev = tmpcard2;
+		    } 
+		    tmpcard2->next = tmpcard->next;
+		    tmpcard->prev = tmpcard2->prev;
+		    tmpcard->next = tmpcard2;
+		    tmpcard2->prev = tmpcard;
+		    changed = 1;
+		    tmpcard = tmpcard2;
+		}
+	    }
+	    tmpcard = tmpcard->next;
+	}
+    } while (changed == 1);
+    spin_unlock(&registerlock);
+    return 0;
+}
+
+int qoz_zapCards(void) {
+    struct qoz_card *tmpcard;
+    tmpcard = qoz_dev_list;
+    while (tmpcard != NULL) {
+	ztqoz_initialize(tmpcard->ztdev);
+	qoz_resetCard(tmpcard);
+	tmpcard = tmpcard->next;
+    }
+    return 0;
+}
+
+
+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, pcmslave %d.\n",qoz_dev_count, totalBRIs, bloop, pcmslave);
+    }
+    return 0;
+}
+
+void cleanup_module(void) {
+    struct qoz_card *tmpcard,*tmplist;
+    int i=0;
+    tmplist = qoz_dev_list;
+    while (tmplist != NULL) {
+	tmplist->dead = 1;
+	qoz_undoWD(tmplist);
+	qoz_shutdownCard(tmplist);
+	tmplist = tmplist->next;
+    }
+    tmplist = qoz_dev_list;
+    spin_lock(&registerlock);
+    while (tmplist != NULL) {
+	tmpcard = tmplist->next;
+	kfree(tmplist);
+	i++;
+	tmplist = tmpcard;
+    }
+    spin_unlock(&registerlock);
+    printk(KERN_INFO "qozap: shutdown %d multiBRI cards.\n", i);
+}
+#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	

Added: zaptel/trunk/qozap/qozap.h
===================================================================
--- zaptel/trunk/qozap/qozap.h	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/qozap.h	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,239 @@
+#define qoz_SPANS 8	
+#define qoz_FIFO_SIZE	128
+#define qoz_DFIFO_SIZE4	2048
+#define qoz_DFIFO_SIZE8	1024
+
+typedef struct qoz_span {
+    unsigned char nt_mode;
+    unsigned char btx;
+    unsigned char bswapped;
+    unsigned char drx;
+    int t3;
+    int t4;
+    unsigned char layer1state;
+} qoz_span;
+
+typedef struct qoz_regs {
+    unsigned char fifo_en;
+    unsigned char ctmt;
+    unsigned char int_m1;
+    unsigned char int_m2;
+    unsigned char sctrl;
+    unsigned char sctrl_e;
+    unsigned char sctrl_r;
+    unsigned char connect;
+    unsigned char trm;
+    unsigned char mst_mode;
+} qoz_regs;
+
+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;
+    unsigned int pcidevfn;
+    struct pci_dev *pcidev;
+    struct zt_qoz *ztdev;
+    unsigned char rxbuf[qoz_SPANS][2][ZT_CHUNKSIZE];
+    unsigned char txbuf[qoz_SPANS][2][ZT_CHUNKSIZE];
+    unsigned char drxbuf[qoz_SPANS][qoz_DFIFO_SIZE4];
+    unsigned char dtxbuf[qoz_SPANS][qoz_DFIFO_SIZE4];
+    unsigned char stports;
+    unsigned int ticks;
+    unsigned int clicks;
+    unsigned int type;
+    unsigned int wdp;
+    struct qoz_card *next;
+    struct qoz_card *prev;
+} qoz_card;
+
+
+typedef struct zt_qoz {
+    unsigned int usecount;
+    struct zt_span spans[qoz_SPANS];
+    struct zt_chan chans[qoz_SPANS][3];
+    struct qoz_card *card;
+} zt_qoz;
+
+#define qoz_outb_io(a,b,c) \
+    outw((b), ((a)->ioport+4)); \
+    outb((c), ((a)->ioport));
+
+#define qoz_inb_io(a,b) ({ outw((b), (a)->ioport+4); inb((a)->ioport); })
+
+#define qoz_outw_io(a,b,c) \
+    outw((b), ((a)->ioport+4)); \
+    outw((c), ((a)->ioport));
+
+#define qoz_inw_io(a,b) ({ outw((b), (a)->ioport+4); inw((a)->ioport); })
+
+#define qoz_outdw_io(a,b,c) \
+    outw((b), ((a)->ioport+4)); \
+    outl((c), ((a)->ioport));
+
+#define qoz_indw_io(a,b) ({ outw((b), (a)->ioport+4); inl((a)->ioport); })
+
+#define qoz_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
+#define qoz_inb(a,b) (readb((a)->pci_io+(b)))
+
+#define qoz_outw(a,b,c) (writew((c),(a)->pci_io+(b)))
+#define qoz_inw(a,b) (readw((a)->pci_io+(b)))
+
+#define qoz_outdw(a,b,c) (writel((c),(a)->pci_io+(b)))
+#define qoz_indw(a,b) (readl((a)->pci_io+(b)))
+
+
+/* Write only registers */
+#define qoz_A_CH_MSK	0xF4
+#define qoz_A_CHANNEL 	0xFC
+#define qoz_A_CON_HDLC	0xFA
+#define qoz_A_CONF	0xD1
+#define qoz_A_FIFO_SEQ	0xFD
+#define qoz_R_INC_RES_FIFO	0x0E
+#define qoz_A_IRQ_MSK	0xFF
+#define qoz_A_SL_CFG	0xD0
+#define qoz_A_ST_B1_TX	0x3C
+#define qoz_A_ST_B2_TX	0x3D
+#define qoz_A_ST_CLK_DLY	0x37
+#define qoz_A_ST_CTRL0	0x31
+#define qoz_A_ST_CTRL1	0x32
+#define qoz_A_ST_CTRL2	0x33
+#define qoz_A_ST_D_TX	0x3E
+#define qoz_A_ST_SQ_WR	0x34
+#define qoz_A_ST_WR_STA	0x30
+#define qoz_A_SUBCH_CFG	0xFB
+#define qoz_R_BERT_WD_MD	0x1B
+#define qoz_R_BRG_CTRL	0x45
+#define qoz_R_BRG_MD	0x47
+#define qoz_R_BRG_PCM_CFG	0x02
+#define qoz_R_BRG_TIM_SEL01	0x4C
+#define qoz_R_BRG_TIM_SEL23	0x4D
+#define qoz_R_BRG_TIM_SEL45	0x4E
+#define qoz_R_BRG_TIM_SEL67	0x4F
+#define qoz_R_BRG_TIM0	0x48
+#define qoz_R_BRG_TIM1	0x49
+#define qoz_R_BRG_TIM2	0x4A
+#define qoz_R_BRG_TIM3	0x4B
+#define qoz_R_CIRM	0x00
+#define qoz_R_CONF_EN	0x18
+#define qoz_R_CTRL	0x01
+#define qoz_R_DTMF0	0x1C
+#define qoz_R_DTMF1	0x1D
+#define qoz_R_FIFO_MD	0x0D
+#define qoz_R_FIFO	0x0F
+#define qoz_R_FIRST_FIFO	0x0B
+#define qoz_R_FSM_IDX	0x0F
+#define qoz_R_GPIO_EN0	0x42
+#define qoz_R_GPIO_EN1	0x43
+#define qoz_R_GPIO_OUT0	0x40
+#define qoz_R_GPIO_OUT1	0x41
+#define qoz_R_GPIO_SEL	0x44
+#define qoz_R_IRQ_CTRL	0x13
+#define qoz_R_IRQMSK_MISC	0x11
+#define qoz_R_PCM_MD0	0x14
+#define qoz_R_PCM_MD1	0x15
+#define qoz_R_PCM_MD2	0x15
+#define qoz_R_PWM_MD	0x46
+#define qoz_R_PWM0	0x38
+#define qoz_R_PWM1	0x39
+#define qoz_R_RAM_ADDR0	0x08
+#define qoz_R_RAM_ADDR1	0x09
+#define qoz_R_RAM_ADDR2	0x0A
+#define qoz_R_RAM_MISC	0x0C
+#define qoz_R_SCI_MSK	0x12
+#define qoz_R_SH0H	0x15
+#define qoz_R_SH0L	0x15
+#define qoz_R_SH1H	0x15
+#define qoz_R_SH1L	0x15
+#define qoz_R_SL_SEL0	0x15
+#define qoz_R_SL_SEL1	0x15
+#define qoz_R_SL_SEL2	0x15
+#define qoz_R_SL_SEL3	0x15
+#define qoz_R_SL_SEL4	0x15
+#define qoz_R_SL_SEL5	0x15
+#define qoz_R_SL_SEL6	0x15
+#define qoz_R_SL_SEL7	0x15
+#define qoz_R_SLOT	0x10
+#define qoz_R_ST_SEL	0x16
+#define qoz_R_ST_SYNC	0x17
+#define qoz_R_TI_WD	0x1A
+
+/* Read only registers */
+#define qoz_A_F1	0x0C
+#define qoz_A_F12	0x0C
+#define qoz_A_F2	0x0D
+#define qoz_A_ST_B1_RX	0x3C
+#define qoz_A_ST_B2_TX	0x3D
+#define qoz_A_ST_D_RX	0x3E
+#define qoz_A_ST_E_RX	0x3F
+#define qoz_A_ST_RD_STA	0x30
+#define qoz_A_ST_SQ_RD	0x34
+#define qoz_A_Z1	0x04
+#define qoz_A_Z12	0x04
+#define qoz_A_Z1H	0x05
+#define qoz_A_Z1L	0x04
+#define qoz_A_Z2	0x06
+#define qoz_A_Z2H	0x07
+#define qoz_A_Z2L	0x06
+#define qoz_R_BERT_ECH	0x1B
+#define qoz_R_BERT_ECL	0x1A
+#define qoz_R_BERT_STA	0x17
+#define qoz_R_CHIP_ID	0x16
+#define qoz_R_CHIP_RV	0x1F
+#define qoz_R_CONF_OFLOW	0x14
+#define qoz_R_F0_CNTH	0x19
+#define qoz_R_F0_CNTL	0x18
+#define qoz_R_GPI_IN0	0x44
+#define qoz_R_GPI_IN1	0x45
+#define qoz_R_GPI_IN2	0x46
+#define qoz_R_GPI_IN3	0x47
+#define qoz_R_GPIO_IN0	0x40
+#define qoz_R_GPIO_IN1	0x41
+#define qoz_R_INT_DATA	0x88
+#define qoz_R_IRQ_FIFO_BL0	0xC8
+#define qoz_R_IRQ_FIFO_BL1	0xC9
+#define qoz_R_IRQ_FIFO_BL2	0xCA
+#define qoz_R_IRQ_FIFO_BL3	0xCB
+#define qoz_R_IRQ_FIFO_BL4	0xCC
+#define qoz_R_IRQ_FIFO_BL5	0xCD
+#define qoz_R_IRQ_FIFO_BL6	0xCE
+#define qoz_R_IRQ_FIFO_BL7	0xCF
+#define qoz_R_IRQ_MISC	0x11
+#define qoz_R_IRQ_OVIEW	0x10
+#define qoz_R_RAM_USE	0x15
+#define qoz_R_SCI	0x12
+#define qoz_R_STATUS	0x1C
+
+/* Read/Write registers */
+#define qoz_A_FIFO_DATA0_NOINC	0x84
+#define qoz_A_FIFO_DATA0	0x80
+#define qoz_A_FIFO_DATA1_NOINC	0x84
+#define qoz_A_FIFO_DATA1	0x80
+#define qoz_A_FIFO_DATA2_NOINC	0x84
+#define qoz_A_FIFO_DATA2	0x80
+#define qoz_R_RAM_DATA	0xC0
+
+#define PCI_DEVICE_ID_CCD_M	0x16b8
+#define PCI_DEVICE_ID_CCD_M4	0x08b4
+#define CLKDEL_TE	0xe	/* CLKDEL in TE mode */
+#define CLKDEL_NT	0xc	/* CLKDEL in NT mode */
+
+#define HFC8S_CHIP_ID	0x80
+#define HFC4S_CHIP_ID	0xC0
+
+#define qoz_WD_P0	0x000000
+#define qoz_WD_P1	0x808080
+#define qoz_WD_P2	0x404040
+
+#define qoz_T3		3
+#define qoz_T4		1
+
+

Added: zaptel/trunk/qozap/zapata.conf
===================================================================
--- zaptel/trunk/qozap/zapata.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/zapata.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,51 @@
+;
+; Zapata telephony interface
+;
+; Configuration file
+
+[channels]
+;
+; Default language
+;
+;language=en
+;
+; Default context
+;
+;
+switchtype = euroisdn
+
+; p2mp TE mode (for connecting ISDN lines in point-to-multipoint mode)
+signalling = bri_cpe_ptmp
+; p2p TE mode (for connecting ISDN lines in point-to-point mode)
+;signalling = bri_cpe
+; p2mp NT mode (for connecting ISDN phones in point-to-multipoint mode)
+;signalling = bri_net_ptmp
+; p2p NT mode (for connecting an ISDN pbx in point-to-point mode)
+;signalling = bri_net
+
+pridialplan = local
+prilocaldialplan = dynamic
+nationalprefix = 0
+internationalprefix = 00
+
+priindication = passthrough
+
+echocancel = yes
+
+context=demo
+group = 1
+; S/T port 1
+channel => 1-2
+
+group = 2
+; S/T port 2
+channel => 4-5
+
+group = 3
+; S/T port 3
+channel => 7-8
+
+group = 4
+; S/T port 4
+channel => 10-11
+

Added: zaptel/trunk/qozap/zapata.conf.octoBRI
===================================================================
--- zaptel/trunk/qozap/zapata.conf.octoBRI	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/zapata.conf.octoBRI	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,67 @@
+;
+; Zapata telephony interface
+;
+; Configuration file
+
+[channels]
+;
+; Default language
+;
+;language=en
+;
+; Default context
+;
+;
+switchtype = euroisdn
+
+; p2mp TE mode (for connecting ISDN lines in point-to-multipoint mode)
+signalling = bri_cpe_ptmp
+; p2p TE mode (for connecting ISDN lines in point-to-point mode)
+;signalling = bri_cpe
+; p2mp NT mode (for connecting ISDN phones in point-to-multipoint mode)
+;signalling = bri_net_ptmp
+; p2p NT mode (for connecting an ISDN pbx in point-to-point mode)
+;signalling = bri_net
+
+pridialplan = local
+prilocaldialplan = dynamic
+nationalprefix = 0
+internationalprefix = 00
+
+priindication = passthrough
+
+echocancel = yes
+
+context=demo
+group = 1
+; S/T port 1
+channel => 1-2
+
+group = 2
+; S/T port 2
+channel => 4-5
+
+group = 3
+; S/T port 3
+channel => 7-8
+
+group = 4
+; S/T port 4
+channel => 10-11
+
+group = 5
+; S/T port 5
+channel => 13-14
+
+group = 6
+; S/T port 6
+channel => 16-17
+
+group = 7
+; S/T port 7
+channel => 19-20
+
+group = 8
+; S/T port 8
+channel => 22-23
+

Added: zaptel/trunk/qozap/zaptel.conf
===================================================================
--- zaptel/trunk/qozap/zaptel.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/zaptel.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,18 @@
+loadzone=nl
+defaultzone=nl
+# qozap span definitions
+# most of the values should be bogus because we are not really zaptel
+span=1,1,3,ccs,ami
+span=2,2,3,ccs,ami
+span=3,0,3,ccs,ami
+span=4,0,3,ccs,ami
+
+bchan=1,2
+dchan=3
+bchan=4,5
+dchan=6
+bchan=7,8
+dchan=9
+bchan=10,11
+dchan=12
+

Added: zaptel/trunk/qozap/zaptel.conf.octoBRI
===================================================================
--- zaptel/trunk/qozap/zaptel.conf.octoBRI	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/qozap/zaptel.conf.octoBRI	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,30 @@
+loadzone=nl
+defaultzone=nl
+# qozap span definitions
+# most of the values should be bogus because we are not really zaptel
+span=1,1,3,ccs,ami
+span=2,0,3,ccs,ami
+span=3,0,3,ccs,ami
+span=4,0,3,ccs,ami
+span=5,1,3,ccs,ami
+span=6,0,3,ccs,ami
+span=7,0,3,ccs,ami
+span=8,0,3,ccs,ami
+
+bchan=1,2
+dchan=3
+bchan=4,5
+dchan=6
+bchan=7,8
+dchan=9
+bchan=10,11
+dchan=12
+bchan=13,14
+dchan=15
+bchan=16,17
+dchan=18
+bchan=19,20
+dchan=21
+bchan=22,23
+dchan=24
+

Added: zaptel/trunk/zaphfc/LICENSE
===================================================================
--- zaptel/trunk/zaphfc/LICENSE	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/LICENSE	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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.

Added: zaptel/trunk/zaphfc/Makefile
===================================================================
--- zaptel/trunk/zaphfc/Makefile	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/Makefile	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,118 @@
+KINCLUDES = /usr/src/linux/include
+BRISTUFFBASE = $(shell dirname `pwd`)
+
+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
+
+CFLAGS+=-I. $(ZAP) $(RTAI) -O2 -g -Wall -DBUILDING_TONEZONE 
+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) $(RTAI) -Wall
+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)
+
+
+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)
+
+OBJS=zaphfc.o
+
+MODULES=zaphfc
+
+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
+
+
+zaphfc.o: zaphfc.c zaphfc.h
+	$(CC) -c zaphfc.c $(KFLAGS)
+
+clean:	
+	rm -f $(OBJS) *.ko *.mod.c *.mod.o .*o.cmd *~
+	rm -rf .tmp_versions
+
+test: all
+	modprobe zaptel
+	insmod ./zaphfc.o
+	cat /proc/interrupts
+	sleep 1
+	cat /proc/interrupts
+	rmmod zaphfc
+	rmmod zaptel
+
+load:	load$(BUILDVER)
+
+loadNT:	load$(BUILDVER)NT
+
+load-debug:	load$(BUILDVER)-debug
+
+loadNT-debug:	load$(BUILDVER)NT-debug
+
+loadlinux24: all
+	modprobe zaptel
+	insmod ./zaphfc.o
+	ztcfg -v
+
+loadlinux24-debug: all
+	modprobe zaptel
+	insmod ./zaphfc.o debug=1
+	ztcfg -v
+
+loadlinux26: linux26
+	modprobe zaptel
+	insmod ./zaphfc.ko
+	ztcfg -v
+
+loadlinux26-debug: linux26
+	modprobe zaptel
+	insmod ./zaphfc.ko debug=1
+	ztcfg -v
+
+loadlinux24NT: all
+	modprobe zaptel
+	insmod ./zaphfc.o modes=1
+	ztcfg -v
+
+loadlinux24NT-debug: all
+	modprobe zaptel
+	insmod ./zaphfc.o modes=1 debug=1
+	ztcfg -v
+
+loadlinux26NT: linux26
+	modprobe zaptel
+	insmod ./zaphfc.ko modes=1
+	ztcfg -v
+
+loadlinux26NT-debug: linux26
+	modprobe zaptel
+	insmod ./zaphfc.ko modes=1 debug=1
+	ztcfg -v
+
+unload: 
+	-rmmod zaphfc zaptel
+
+zaphfc.ko: zaphfc.c zaphfc.h
+
+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
+
+install:	install$(BUILDVER)
+
+installlinux26:
+	install -D -m 644 zaphfc.ko $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.ko
+
+installlinux24:
+	install -D -m 644 zaphfc.o $(INSTALL_PREFIX)/lib/modules/`uname -r`/misc/zaphfc.o
+

Added: zaptel/trunk/zaphfc/zapata.conf
===================================================================
--- zaptel/trunk/zaphfc/zapata.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/zapata.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,38 @@
+;
+; Zapata telephony interface
+;
+; Configuration file
+
+[channels]
+;
+; Default language
+;
+;language=en
+;
+; Default context
+;
+;
+switchtype = euroisdn
+; p2mp TE mode
+signalling = bri_cpe_ptmp
+
+; p2p TE mode
+;signalling = bri_cpe
+; p2mp NT mode
+;signalling = bri_net_ptmp
+; p2p NT mode
+;signalling = bri_net
+
+pridialplan = dynamic
+prilocaldialplan = local
+nationalprefix = 0
+internationalprefix = 00
+
+echocancel=yes
+echotraining = 100
+echocancelwhenbridged=yes
+
+immediate=yes
+group = 1
+context=demo
+channel => 1-2

Added: zaptel/trunk/zaphfc/zaphfc.c
===================================================================
--- zaptel/trunk/zaphfc/zaphfc.c	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/zaphfc.c	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,1155 @@
+/*
+ * zaphfc.c - Zaptel driver for HFC-S PCI A based ISDN BRI cards
+ *
+ * kernel module inspired by HFC PCI ISDN4Linux and Zaptel drivers
+ *
+ * Copyright (C) 2002, 2003, 2004, 2005 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>
+#ifdef RTAITIMING
+#include <asm/io.h>
+#include <rtai.h>
+#include <rtai_sched.h>
+#include <rtai_fifos.h>
+#endif
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <zaptel.h>
+#include "zaphfc.h"
+
+#if CONFIG_PCI
+
+#define CLKDEL_TE	0x0f	/* CLKDEL in TE mode */
+#define CLKDEL_NT	0x6c	/* CLKDEL in NT mode */
+
+typedef struct {
+        int vendor_id;
+        int device_id;
+        char *vendor_name;
+        char *card_name;
+} PCI_ENTRY;
+
+static const PCI_ENTRY id_list[] =
+{
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_2BD0, "CCD/Billion/Asuscom", "2BD0"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B000, "Billion", "B000"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B006, "Billion", "B006"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B007, "Billion", "B007"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B008, "Billion", "B008"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B009, "Billion", "B009"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00A, "Billion", "B00A"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00B, "Billion", "B00B"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B00C, "Billion", "B00C"},
+        {PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_B100, "Seyeon", "B100"},
+        {PCI_VENDOR_ID_ABOCOM, PCI_DEVICE_ID_ABOCOM_2BD1, "Abocom/Magitek", "2BD1"},
+        {PCI_VENDOR_ID_ASUSTEK, PCI_DEVICE_ID_ASUSTEK_0675, "Asuscom/Askey", "675"},
+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_T_CONCEPT, "German telekom", "T-Concept"},
+        {PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_A1T, "German telekom", "A1T"},
+        {PCI_VENDOR_ID_ANIGMA, PCI_DEVICE_ID_ANIGMA_MC145575, "Motorola MC145575", "MC145575"},
+        {PCI_VENDOR_ID_ZOLTRIX, PCI_DEVICE_ID_ZOLTRIX_2BD0, "Zoltrix", "2BD0"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_E,"Digi International", "Digi DataFire Micro V IOM2 (Europe)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_E,"Digi International", "Digi DataFire Micro V (Europe)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_IOM2_A,"Digi International", "Digi DataFire Micro V IOM2 (North America)"},
+        {PCI_VENDOR_ID_DIGI, PCI_DEVICE_ID_DIGI_DF_M_A,"Digi International", "Digi DataFire Micro V (North America)"},
+	{0x182d, 0x3069,"Sitecom","Isdn 128 PCI"},
+        {0, 0, NULL, NULL},
+};
+
+static struct hfc_card *hfc_dev_list = NULL;
+static int hfc_dev_count = 0;
+static int modes = 0; // all TE
+static int debug = 0;
+static struct pci_dev *multi_hfc = NULL;
+static spinlock_t registerlock = SPIN_LOCK_UNLOCKED;
+
+void hfc_shutdownCard(struct hfc_card *hfctmp) {
+    unsigned long flags;
+
+    if (hfctmp == NULL) {
+	return;
+    }
+
+    if (hfctmp->pci_io == NULL) {
+	return;
+    }
+    
+    spin_lock_irqsave(&hfctmp->lock,flags);
+
+    printk(KERN_INFO "zaphfc: shutting down card at %p.\n",hfctmp->pci_io);
+
+    /* Clear interrupt mask */
+    hfctmp->regs.int_m2 = 0;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+    /* Reset pending interrupts */
+    hfc_inb(hfctmp, hfc_INT_S1);
+
+    /* Wait for interrupts that might still be pending */
+    spin_unlock_irqrestore(&hfctmp->lock, flags);
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
+    spin_lock_irqsave(&hfctmp->lock,flags);
+
+    /* Remove interrupt handler */
+    if (hfctmp->irq) {
+	free_irq(hfctmp->irq, hfctmp);
+    }
+
+    /* Soft-reset the card */
+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET); // softreset on
+
+    spin_unlock_irqrestore(&hfctmp->lock, flags);
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
+    spin_lock_irqsave(&hfctmp->lock,flags);
+
+    hfc_outb(hfctmp,hfc_CIRM,0);	// softreset off
+
+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, 0);	// disable memio and bustmaster
+
+    if (hfctmp->fifomem != NULL) {
+        kfree(hfctmp->fifomem);
+    }
+    iounmap((void *) hfctmp->pci_io);
+    hfctmp->pci_io = NULL;
+    if (hfctmp->pcidev != NULL) {
+        pci_disable_device(hfctmp->pcidev);
+    }
+    spin_unlock_irqrestore(&hfctmp->lock,flags);
+    if (hfctmp->ztdev != NULL) {
+	zt_unregister(&hfctmp->ztdev->span);
+	kfree(hfctmp->ztdev);
+	printk(KERN_INFO "unregistered from zaptel.\n");
+    }
+}
+
+void hfc_resetCard(struct hfc_card *hfctmp) {
+    unsigned long flags;
+
+    spin_lock_irqsave(&hfctmp->lock,flags);
+    pci_write_config_word(hfctmp->pcidev, PCI_COMMAND, PCI_COMMAND_MEMORY);	// enable memio
+    hfctmp->regs.int_m2 = 0;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+//    printk(KERN_INFO "zaphfc: resetting card.\n");
+    pci_set_master(hfctmp->pcidev);
+    hfc_outb(hfctmp, hfc_CIRM, hfc_CIRM_RESET);	// softreset on
+    spin_unlock_irqrestore(&hfctmp->lock, flags);
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((30 * HZ) / 1000);	// wait 30 ms
+    hfc_outb(hfctmp, hfc_CIRM, 0);	// softreset off
+
+    set_current_state(TASK_UNINTERRUPTIBLE);
+    schedule_timeout((20 * HZ) / 1000);	// wait 20 ms
+    if (hfc_inb(hfctmp,hfc_STATUS) & hfc_STATUS_PCI_PROC) {
+	printk(KERN_WARNING "zaphfc: hfc busy.\n");
+    }
+
+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
+//    hfctmp->regs.fifo_en = hfc_FIFOEN_D;	/* only D fifos enabled */
+    hfctmp->regs.fifo_en = 0;	/* no fifos enabled */
+    hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
+
+    hfctmp->regs.trm = 2;
+    hfc_outb(hfctmp, hfc_TRM, hfctmp->regs.trm);
+
+    if (hfctmp->regs.nt_mode == 1) {
+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_NT); /* ST-Bit delay for NT-Mode */
+    } else {
+	hfc_outb(hfctmp, hfc_CLKDEL, CLKDEL_TE); /* ST-Bit delay for TE-Mode */
+    }
+    hfctmp->regs.sctrl_e = hfc_SCTRL_E_AUTO_AWAKE;
+    hfc_outb(hfctmp, hfc_SCTRL_E, hfctmp->regs.sctrl_e);	/* S/T Auto awake */
+    hfctmp->regs.bswapped = 0;	/* no exchange */
+
+    hfctmp->regs.ctmt = hfc_CTMT_TRANSB1 | hfc_CTMT_TRANSB2; // all bchans are transparent , no freaking hdlc
+    hfc_outb(hfctmp, hfc_CTMT, hfctmp->regs.ctmt);
+
+    hfctmp->regs.int_m1 = 0;
+    hfc_outb(hfctmp, hfc_INT_M1, hfctmp->regs.int_m1);
+
+#ifdef RTAITIMING
+    hfctmp->regs.int_m2 = 0;
+#else
+    hfctmp->regs.int_m2 = hfc_M2_PROC_TRANS;
+#endif
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+
+    /* Clear already pending ints */
+    hfc_inb(hfctmp, hfc_INT_S1);
+
+    if (hfctmp->regs.nt_mode == 1) {
+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_NT;	/* set tx_lo mode, error in datasheet ! */
+    } else {
+	hfctmp->regs.sctrl = 3 | hfc_SCTRL_NONE_CAP | hfc_SCTRL_MODE_TE;	/* set tx_lo mode, error in datasheet ! */
+    }
+
+    hfctmp->regs.mst_mode = hfc_MST_MODE_MASTER;	/* HFC Master Mode */
+    hfc_outb(hfctmp, hfc_MST_MODE, hfctmp->regs.mst_mode);
+
+    hfc_outb(hfctmp, hfc_SCTRL, hfctmp->regs.sctrl);
+    hfctmp->regs.sctrl_r = 3;
+    hfc_outb(hfctmp, hfc_SCTRL_R, hfctmp->regs.sctrl_r);
+
+    hfctmp->regs.connect = 0;
+    hfc_outb(hfctmp, hfc_CONNECT, hfctmp->regs.connect);
+
+    hfc_outb(hfctmp, hfc_CIRM, 0x80 | 0x40);	// bit order
+
+    /* Finally enable IRQ output */
+#ifndef RTAITIMING
+    hfctmp->regs.int_m2 |= hfc_M2_IRQ_ENABLE;
+    hfc_outb(hfctmp, hfc_INT_M2, hfctmp->regs.int_m2);
+#endif
+
+    /* clear pending ints */
+    hfc_inb(hfctmp, hfc_INT_S1); 
+    hfc_inb(hfctmp, hfc_INT_S2);
+}
+
+void hfc_registerCard(struct hfc_card *hfccard) {
+    spin_lock(&registerlock);
+    if (hfccard != NULL) {
+	hfccard->cardno = hfc_dev_count++;
+	hfccard->next = hfc_dev_list;
+	hfc_dev_list = hfccard;
+    }
+    spin_unlock(&registerlock);
+}
+
+static void hfc_btrans(struct hfc_card *hfctmp, char whichB) {
+    // we are called with irqs disabled from the irq handler
+    int count, maxlen, total;
+    unsigned char *f1, *f2;
+    unsigned short *z1, *z2, newz1;
+    int freebytes;
+
+    if (whichB == 1) {
+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F1);
+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1TX_F2);
+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z1 + (*f1 * 4));
+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1TX_Z2 + (*f1 * 4));
+    } else {
+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F1);
+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2TX_F2);
+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z1 + (*f1 * 4));
+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2TX_Z2 + (*f1 * 4));
+    }
+
+    freebytes = *z2 - *z1;
+    if (freebytes <= 0) {
+	freebytes += hfc_B_FIFO_SIZE;
+    }
+    count = ZT_CHUNKSIZE;
+
+    total = count;
+    if (freebytes < count) {
+	hfctmp->clicks++;
+	/* only spit out this warning once per second to not make things worse! */
+	if (hfctmp->clicks > 100) {
+	    printk(KERN_CRIT "zaphfc: bchan tx fifo full, dropping audio! (z1=%d, z2=%d)\n",*z1,*z2);
+	    hfctmp->clicks = 0;
+	}
+	return;
+    }
+    
+    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z1;
+    if (maxlen > count) {
+        maxlen = count;
+    }
+    newz1 = *z1 + total;
+    if (newz1 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { newz1 -= hfc_B_FIFO_SIZE; }
+
+	if (whichB == 1) {
+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + *z1),hfctmp->ztdev->chans[0].writechunk, maxlen);
+	} else {
+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + *z1),hfctmp->ztdev->chans[1].writechunk, maxlen);
+	}
+	
+	count -= maxlen;
+	if (count > 0) {
+	// Buffer wrap
+	    if (whichB == 1) {
+	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B1TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[0].writechunk+maxlen, count);
+	    } else {
+	        memcpy((char *)(hfctmp->fifos + hfc_FIFO_B2TX_ZOFF + hfc_B_SUB_VAL),hfctmp->ztdev->chans[1].writechunk+maxlen, count);
+	    }
+	}
+
+    *z1 = newz1;	/* send it now */
+
+//    if (count > 0) printk(KERN_CRIT "zaphfc: bchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
+    return;    
+}
+
+static void hfc_brec(struct hfc_card *hfctmp, char whichB) {
+    // we are called with irqs disabled from the irq handler
+    int count, maxlen, drop;
+    volatile unsigned char *f1, *f2;
+    volatile unsigned short *z1, *z2, newz2;
+    int bytes = 0;
+
+    if (whichB == 1) {
+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F1);
+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B1RX_F2);
+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z1 + (*f1 * 4));
+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
+    } else {
+	f1 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F1);
+        f2 = (char *)(hfctmp->fifos + hfc_FIFO_B2RX_F2);
+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z1 + (*f1 * 4));
+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
+    }
+
+    bytes = *z1 - *z2;
+    if (bytes < 0) {
+	bytes += hfc_B_FIFO_SIZE;
+    }
+    count = ZT_CHUNKSIZE;
+    
+    if (bytes < ZT_CHUNKSIZE) {
+#ifndef RTAITIMING
+	printk(KERN_CRIT "zaphfc: bchan rx fifo not enough bytes to receive! (z1=%d, z2=%d, wanted %d got %d), probably a buffer overrun.\n",*z1,*z2,ZT_CHUNKSIZE,bytes);
+#endif
+	return;
+    }
+
+    /* allowing the buffering of hfc_BCHAN_BUFFER bytes of audio data works around irq jitter */
+    if (bytes > hfc_BCHAN_BUFFER + ZT_CHUNKSIZE) {
+	/* if the system is too slow to handle it, we will have to drop it all (except 1 zaptel chunk) */
+	drop = bytes - ZT_CHUNKSIZE;
+	hfctmp->clicks++;
+	/* only spit out this warning once per second to not make things worse! */
+	if (hfctmp->clicks > 100) {
+	    printk(KERN_CRIT "zaphfc: dropped audio (z1=%d, z2=%d, wanted %d got %d, dropped %d).\n",*z1,*z2,count,bytes,drop);
+	    hfctmp->clicks = 0;
+	}
+	/* hm, we are processing the b chan data tooooo slowly... let's drop the lost audio */
+	newz2 = *z2 + drop;
+	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
+	    newz2 -= hfc_B_FIFO_SIZE; 
+	}
+	*z2 = newz2;
+    }
+
+    
+    maxlen = (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL) - *z2;
+    if (maxlen > count) {
+        maxlen = count;
+    }
+    if (whichB == 1) {
+        memcpy(hfctmp->ztdev->chans[0].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + *z2), maxlen);
+    } else {
+        memcpy(hfctmp->ztdev->chans[1].readchunk,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + *z2), maxlen);
+    }
+    newz2 = *z2 + count;
+    if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
+        newz2 -= hfc_B_FIFO_SIZE; 
+    }
+    *z2 = newz2;
+	
+    count -= maxlen;
+    if (count > 0) {
+    // Buffer wrap
+        if (whichB == 1) {
+	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B1RX_Z2 + (*f1 * 4));
+    	    memcpy(hfctmp->ztdev->chans[0].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B1RX_ZOFF + hfc_B_SUB_VAL), count);
+	} else {
+	    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_B2RX_Z2 + (*f1 * 4));
+	    memcpy(hfctmp->ztdev->chans[1].readchunk + maxlen,(char *)(hfctmp->fifos + hfc_FIFO_B2RX_ZOFF + hfc_B_SUB_VAL), count);
+	}
+	newz2 = *z2 + count;
+	if (newz2 >= (hfc_B_FIFO_SIZE + hfc_B_SUB_VAL)) { 
+	    newz2 -= hfc_B_FIFO_SIZE; 
+	}
+    }
+
+
+    if (whichB == 1) {
+	zt_ec_chunk(&hfctmp->ztdev->chans[0], hfctmp->ztdev->chans[0].readchunk, hfctmp->ztdev->chans[0].writechunk);
+    } else {
+	zt_ec_chunk(&hfctmp->ztdev->chans[1], hfctmp->ztdev->chans[1].readchunk, hfctmp->ztdev->chans[1].writechunk);
+    }
+    return;    
+}
+
+
+static void hfc_dtrans(struct hfc_card *hfctmp) {
+    // we are called with irqs disabled from the irq handler
+    int x;
+    int count, maxlen, total;
+    unsigned char *f1, *f2, newf1;
+    unsigned short *z1, *z2, newz1;
+    int frames, freebytes;
+
+    if (hfctmp->ztdev->chans[2].bytes2transmit == 0) {
+	return;
+    }
+
+    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F1);
+    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DTX_F2);
+    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z2 + (*f1 * 4));
+
+    frames = (*f1 - *f2) & hfc_FMASK;
+    if (frames < 0) {
+	frames += hfc_MAX_DFRAMES + 1;
+    }
+
+    if (frames >= hfc_MAX_DFRAMES) {
+	printk(KERN_CRIT "zaphfc: dchan tx fifo total number of frames exceeded!\n");
+	return;
+    }
+
+    freebytes = *z2 - *z1;
+    if (freebytes <= 0) {
+	freebytes += hfc_D_FIFO_SIZE;
+    }
+    count = hfctmp->ztdev->chans[2].bytes2transmit;
+
+    total = count;
+    if (freebytes < count) {
+	printk(KERN_CRIT "zaphfc: dchan tx fifo not enough free bytes! (z1=%d, z2=%d)\n",*z1,*z2);
+	return;
+    }
+    
+    newz1 = (*z1 + count) & hfc_ZMASK;
+    newf1 = ((*f1 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	// next frame
+    
+    if (count > 0) {
+	if (debug) {
+    	    printk(KERN_CRIT "zaphfc: card %d TX [ ", hfctmp->cardno);
+	    for (x=0; x<count; x++) {
+		printk("%#2x ",hfctmp->dtransbuf[x]);
+	    }
+	    if (hfctmp->ztdev->chans[2].eoftx == 1) {
+		printk("] %d bytes\n", count);
+	    } else {
+		printk("..] %d bytes\n", count);
+	    }
+	}
+	maxlen = hfc_D_FIFO_SIZE - *z1;
+	if (maxlen > count) {
+	    maxlen = count;
+	}
+	memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF + *z1),hfctmp->ztdev->chans[2].writechunk, maxlen);
+	count -= maxlen;
+	if (count > 0) {
+	    memcpy((char *)(hfctmp->fifos + hfc_FIFO_DTX_ZOFF),(char *)(hfctmp->ztdev->chans[2].writechunk + maxlen), count);
+	}
+    }
+
+    *z1 = newz1;
+
+    if (hfctmp->ztdev->chans[2].eoftx == 1) {
+	*f1 = newf1;
+	z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DTX_Z1 + (*f1 * 4));
+	*z1 = newz1;
+	hfctmp->ztdev->chans[2].eoftx = 0;
+    }
+//    printk(KERN_CRIT "zaphfc: dchan tx fifo (f1=%d, f2=%d, z1=%d, z2=%d)\n",(*f1) & hfc_FMASK,(*f2) & hfc_FMASK, *z1, *z2);
+    return;    
+}
+
+/* receive a complete hdlc frame, skip broken or short frames */
+static void hfc_drec(struct hfc_card *hfctmp) {
+    int count=0, maxlen=0, framelen=0;
+    unsigned char *f1, *f2, *crcstat;
+    unsigned short *z1, *z2, oldz2, newz2;
+
+    hfctmp->ztdev->chans[2].bytes2receive=0;
+    hfctmp->ztdev->chans[2].eofrx = 0;
+
+    /* put the received data into the zaptel buffer
+       we'll call zt_receive() later when the timer fires. */
+    f1 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F1);
+    f2 = (char *)(hfctmp->fifos + hfc_FIFO_DRX_F2);
+
+    if (*f1 == *f2) return; /* nothing received, strange eh? */
+
+    z1 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z1 + (*f2 * 4));
+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
+    
+    /* calculate length of frame, including 2 bytes CRC and 1 byte STAT */
+    count = *z1 - *z2;
+    
+    if (count < 0) { 
+	count += hfc_D_FIFO_SIZE; /* ring buffer wrapped */
+    }
+    count++;
+    framelen = count;
+
+    crcstat = (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z1);
+
+    if ((framelen < 4) || (*crcstat != 0x0)) {
+	/* the frame is too short for a valid HDLC frame or the CRC is borked */
+	printk(KERN_CRIT "zaphfc: empty HDLC frame or bad CRC received (framelen = %d, stat = %#x, card = %d).\n", framelen, *crcstat, hfctmp->cardno);
+	oldz2 = *z2;
+	*f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
+        // recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!!
+	z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
+	*z2 = (oldz2 + framelen) & hfc_ZMASK;
+	hfctmp->drecinframe = 0;
+	hfctmp->regs.int_drec--;
+	/* skip short or broken frames */
+        hfctmp->ztdev->chans[2].bytes2receive = 0; 
+	return;
+    }
+
+    count -= 1;	/* strip STAT */
+    hfctmp->ztdev->chans[2].eofrx = 1;
+
+    if (count + *z2 <= hfc_D_FIFO_SIZE) {
+	maxlen = count;
+    } else {
+	maxlen = hfc_D_FIFO_SIZE - *z2;
+    }
+
+    /* copy first part */
+    memcpy(hfctmp->drecbuf, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF + *z2), maxlen);
+    hfctmp->ztdev->chans[2].bytes2receive += maxlen; 
+    
+    count -= maxlen;
+    if (count > 0) {
+	/* ring buffer wrapped, copy rest from start of d fifo */
+	memcpy(hfctmp->drecbuf + maxlen, (char *)(hfctmp->fifos + hfc_FIFO_DRX_ZOFF), count);
+	hfctmp->ztdev->chans[2].bytes2receive += count; 
+    }
+
+    /* frame read */
+    oldz2 = *z2;
+    newz2 = (oldz2 + framelen) & hfc_ZMASK;
+    *f2 = ((*f2 + 1) & hfc_MAX_DFRAMES) | (hfc_MAX_DFRAMES + 1);	/* NEXT!!! */
+    /* recalculate z2, because Z2 is a function of F2 Z2(F2) and we INCed F2!!! */
+    z2 = (unsigned short *)(hfctmp->fifos + hfc_FIFO_DRX_Z2 + (*f2 * 4));
+    *z2 = newz2;
+    hfctmp->drecinframe = 0;
+    hfctmp->regs.int_drec--; 
+}
+
+#ifndef RTAITIMING
+#ifdef LINUX26
+static irqreturn_t hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
+#else
+static void hfc_interrupt(int irq, void *dev_id, struct pt_regs *regs) {
+#endif
+    struct hfc_card *hfctmp = dev_id;
+    unsigned long flags = 0;
+    unsigned char stat;
+#else
+static void hfc_service(struct hfc_card *hfctmp) {
+#endif
+    struct zt_hfc *zthfc;
+    unsigned char s1, s2, l1state;
+    int x;
+
+    if (!hfctmp) {
+#ifndef RTAITIMING
+#ifdef LINUX26
+		return IRQ_NONE;
+#else
+		return;
+#endif		
+#else
+	/* rtai */
+	return;
+#endif
+    }
+
+    if (!hfctmp->pci_io) {
+	    printk(KERN_WARNING "%s: IO-mem disabled, cannot handle interrupt\n",
+		   __FUNCTION__);
+#ifndef RTAITIMING
+#ifdef LINUX26
+	    return IRQ_NONE;
+#else
+	    return;
+#endif		
+#else
+	/* rtai */
+	return;
+#endif
+    }
+    
+    /*	we assume a few things in this irq handler:
+	- the hfc-pci will only generate "timer" irqs (proc/non-proc)
+	- we need to use every 8th IRQ (to generate 1khz timing)
+	OR
+	- if we use rtai for timing the hfc-pci will not generate ANY irq,
+	  instead rtai will call this "fake" irq with a 1khz realtime timer. :)
+	- rtai will directly service the card, not like it used to by triggering
+	  the linux irq
+    */
+
+#ifndef RTAITIMING
+    spin_lock_irqsave(&hfctmp->lock, flags);
+    stat = hfc_inb(hfctmp, hfc_STATUS);
+
+    if ((stat & hfc_STATUS_ANYINT) == 0) {
+        // maybe we are sharing the irq
+	spin_unlock_irqrestore(&hfctmp->lock,flags);
+#ifdef LINUX26
+	return IRQ_NONE;
+#else
+	return;
+#endif		
+    }
+#endif
+
+    s1 = hfc_inb(hfctmp, hfc_INT_S1);
+    s2 = hfc_inb(hfctmp, hfc_INT_S2); 
+    if (s1 != 0) {
+	if (s1 & hfc_INTS_TIMER) {
+	    // timer (bit 7)
+	    // printk(KERN_CRIT "timer %d %d %d.\n", stat, s1, s2);
+	}
+	if (s1 & hfc_INTS_L1STATE) {
+	    // state machine (bit 6)
+	    // printk(KERN_CRIT "zaphfc: layer 1 state machine interrupt\n");
+	    zthfc = hfctmp->ztdev;
+	    l1state = hfc_inb(hfctmp,hfc_STATES)  & hfc_STATES_STATE_MASK;
+	    if (hfctmp->regs.nt_mode == 1) {
+		if (debug) {
+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = G%d\n", hfctmp->cardno, l1state);
+		}
+		switch (l1state) {
+		    case 3:
+#ifdef RTAITIMING
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
+#else
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 ACTIVATED (G%d)", hfctmp->cardno, l1state);
+#endif
+			break;
+		    default:
+#ifdef RTAITIMING
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d) [realtime]", hfctmp->cardno, l1state);
+#else
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] layer 1 DEACTIVATED (G%d)", hfctmp->cardno, l1state);
+#endif
+		}
+		if (l1state == 2) {
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_ACTIVATE | hfc_STATES_DO_ACTION | hfc_STATES_NT_G2_G3);
+		} else if (l1state == 3) {
+		    // fix to G3 state (see specs)
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_LOAD_STATE | 3);
+		}
+	    } else {
+		if (debug) {
+	    	    printk(KERN_CRIT "zaphfc: card %d layer 1 state = F%d\n", hfctmp->cardno, l1state);
+		}
+		switch (l1state) {
+		    case 7:
+#ifdef RTAITIMING
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
+#else
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 ACTIVATED (F%d)", hfctmp->cardno, l1state);
+#endif
+			break;
+		    default:
+#ifdef RTAITIMING
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d) [realtime]", hfctmp->cardno, l1state);
+#else
+			sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] layer 1 DEACTIVATED (F%d)", hfctmp->cardno, l1state);
+#endif
+		}
+		if (l1state == 3) {
+		    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
+		}
+	    }
+	    
+	}
+	if (s1 & hfc_INTS_DREC) {
+	    // D chan RX (bit 5)
+	    hfctmp->regs.int_drec++;
+	    // mr. zapata there is something for you!
+	//    printk(KERN_CRIT "d chan rx\n");		    
+	}
+	if (s1 & hfc_INTS_B2REC) {
+	    // B2 chan RX (bit 4)
+	}
+	if (s1 & hfc_INTS_B1REC) {
+	    // B1 chan RX (bit 3)
+	}
+	if (s1 & hfc_INTS_DTRANS) {
+	    // D chan TX (bit 2)
+//	    printk(KERN_CRIT "zaphfc: dchan frame transmitted.\n");
+	}
+	if (s1 & hfc_INTS_B2TRANS) {
+	    // B2 chan TX (bit 1)
+	}
+	if (s1 & hfc_INTS_B1TRANS) {
+	    // B1 chan TX (bit 0)
+	}
+    }
+#ifdef RTAITIMING
+    /* fake an irq */
+    s2 |= hfc_M2_PROC_TRANS;
+#endif
+    if (s2 != 0) {
+	if (s2 & hfc_M2_PMESEL) {
+	    // kaboom irq (bit 7)
+	    printk(KERN_CRIT "zaphfc: sync lost, pci performance too low. you might have some cpu throtteling enabled.\n");
+	}
+	if (s2 & hfc_M2_GCI_MON_REC) {
+	    // RxR monitor channel (bit 2)
+	}
+	if (s2 & hfc_M2_GCI_I_CHG) {
+	    // GCI I-change  (bit 1)
+	}
+	if (s2 & hfc_M2_PROC_TRANS) {
+	    // processing/non-processing transition  (bit 0)
+	    hfctmp->ticks++;
+#ifndef RTAITIMING
+	    if (hfctmp->ticks > 7) {
+		// welcome to zaptel timing :)
+#endif
+	    	hfctmp->ticks = 0;
+
+		if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
+		    // clear dchan buffer
+		    hfctmp->ztdev->chans[2].bytes2transmit = 0;
+		    hfctmp->ztdev->chans[2].maxbytes2transmit = hfc_D_FIFO_SIZE;
+
+		    zt_transmit(&(hfctmp->ztdev->span));
+
+		    hfc_btrans(hfctmp,1);
+		    hfc_btrans(hfctmp,2);
+		    hfc_dtrans(hfctmp);
+		}
+
+		hfc_brec(hfctmp,1);
+		hfc_brec(hfctmp,2);
+		if (hfctmp->regs.int_drec > 0) {
+		    // dchan data to read
+		    hfc_drec(hfctmp);
+		    if (hfctmp->ztdev->chans[2].bytes2receive > 0) {
+			    if (debug) {
+    				printk(KERN_CRIT "zaphfc: card %d RX [ ", hfctmp->cardno);
+				if (hfctmp->ztdev->chans[2].eofrx) {
+				    /* dont output CRC == less user confusion */
+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive - 2; x++) {
+					printk("%#2x ", hfctmp->drecbuf[x]);
+				    }
+				    printk("] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive - 2);
+				} else {
+				    for (x=0; x < hfctmp->ztdev->chans[2].bytes2receive; x++) {
+					printk("%#2x ", hfctmp->drecbuf[x]);
+				    }
+				    printk("..] %d bytes\n", hfctmp->ztdev->chans[2].bytes2receive);
+				}
+			    }
+		    }
+		} else {
+			// hmm....ok, let zaptel receive nothing
+		    hfctmp->ztdev->chans[2].bytes2receive = 0;
+		}
+		if (hfctmp->ztdev->span.flags & ZT_FLAG_RUNNING) {
+		    zt_receive(&(hfctmp->ztdev->span));
+		}
+		
+#ifndef RTAITIMING
+	    }
+#endif
+	}
+
+    }
+#ifndef RTAITIMING
+    spin_unlock_irqrestore(&hfctmp->lock,flags);
+#ifdef LINUX26
+	return IRQ_RETVAL(1);
+#endif		
+#endif
+}
+
+
+static int zthfc_open(struct zt_chan *chan) {
+    struct zt_hfc *zthfc = chan->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+    
+    if (!hfctmp) {
+    return 0;
+    }
+#ifndef LINUX26  
+    MOD_INC_USE_COUNT;
+#else
+    try_module_get(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int zthfc_close(struct zt_chan *chan) {
+    struct zt_hfc *zthfc = chan->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+
+    if (!hfctmp) {
+	return 0;
+    }
+
+#ifndef LINUX26  
+    MOD_DEC_USE_COUNT;
+#else
+    module_put(THIS_MODULE);
+#endif
+    return 0;
+}
+
+static int zthfc_rbsbits(struct zt_chan *chan, int bits) {
+    return 0;
+}
+
+static int zthfc_ioctl(struct zt_chan *chan, unsigned int cmd, unsigned long data) {
+        switch(cmd) {
+        default:
+                return -ENOTTY;
+        }
+        return 0;
+}
+
+static int zthfc_startup(struct zt_span *span) {
+    struct zt_hfc *zthfc = span->pvt;
+    struct hfc_card *hfctmp = zthfc->card;
+    int alreadyrunning;
+    
+    if (hfctmp == NULL) {
+	printk(KERN_INFO "zaphfc: no card for span at startup!\n");
+    }
+    alreadyrunning = span->flags & ZT_FLAG_RUNNING;
+    
+    if (!alreadyrunning) {
+	span->chans[2].flags &= ~ZT_FLAG_HDLC;
+	span->chans[2].flags |= ZT_FLAG_BRIDCHAN;
+	
+	span->flags |= ZT_FLAG_RUNNING;
+
+	hfctmp->ticks = -2;
+	hfctmp->clicks = 0;
+	hfctmp->regs.fifo_en = hfc_FIFOEN_D | hfc_FIFOEN_B1 | hfc_FIFOEN_B2;
+        hfc_outb(hfctmp, hfc_FIFO_EN, hfctmp->regs.fifo_en);
+    } else {
+	return 0;
+    }
+
+    // drivers, start engines!
+    hfc_outb(hfctmp, hfc_STATES, hfc_STATES_DO_ACTION | hfc_STATES_ACTIVATE);
+    return 0;
+}
+
+static int zthfc_shutdown(struct zt_span *span) {
+    return 0;
+}
+
+static int zthfc_maint(struct zt_span *span, int cmd) {
+    return 0;
+}
+
+static int zthfc_chanconfig(struct zt_chan *chan, int sigtype) {
+//    printk(KERN_CRIT "chan_config sigtype=%d\n", sigtype);
+    return 0;
+}
+
+static int zthfc_spanconfig(struct zt_span *span, struct zt_lineconfig *lc) {
+    span->lineconfig = lc->lineconfig;
+    return 0;
+}
+
+static int zthfc_initialize(struct zt_hfc *zthfc) {
+    struct hfc_card *hfctmp = zthfc->card;
+    int i;
+
+    memset(&zthfc->span, 0x0, sizeof(struct zt_span)); // you never can tell...
+
+    sprintf(zthfc->span.name, "ZTHFC%d", hfc_dev_count + 1);
+    if (hfctmp->regs.nt_mode == 1) {
+#ifdef RTAITIMING
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT] [realtime]", hfc_dev_count + 1);
+#else
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [NT]", hfc_dev_count + 1);
+#endif
+    } else {
+#ifdef RTAITIMING
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE] [realtime]", hfc_dev_count + 1);
+#else
+	sprintf(zthfc->span.desc, "HFC-S PCI A ISDN card %d [TE]", hfc_dev_count + 1);
+#endif
+    }
+
+    zthfc->span.spanconfig = zthfc_spanconfig;
+    zthfc->span.chanconfig = zthfc_chanconfig;
+    zthfc->span.startup = zthfc_startup;
+    zthfc->span.shutdown = zthfc_shutdown;
+    zthfc->span.maint = zthfc_maint;
+    zthfc->span.rbsbits = zthfc_rbsbits;
+    zthfc->span.open = zthfc_open;
+    zthfc->span.close = zthfc_close;
+    zthfc->span.ioctl = zthfc_ioctl;
+
+    zthfc->span.chans = zthfc->chans;
+    zthfc->span.channels = 3;
+    zthfc->span.deflaw = ZT_LAW_ALAW;
+    zthfc->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS; // <--- this is really BS
+    zthfc->span.offset = 0;
+    init_waitqueue_head(&zthfc->span.maintq);
+    zthfc->span.pvt = zthfc;
+
+    for (i = 0; i < zthfc->span.channels; i++) {
+	memset(&(zthfc->chans[i]), 0x0, sizeof(struct zt_chan));
+	sprintf(zthfc->chans[i].name, "ZTHFC%d/%d/%d", hfc_dev_count + 1,0,i + 1);
+	zthfc->chans[i].pvt = zthfc;
+	zthfc->chans[i].sigcap =  ZT_SIG_EM | ZT_SIG_CLEAR | ZT_SIG_FXSLS | ZT_SIG_FXSGS | ZT_SIG_FXSKS | ZT_SIG_FXOLS | ZT_SIG_FXOGS | ZT_SIG_FXOKS | ZT_SIG_CAS | ZT_SIG_SF;
+	zthfc->chans[i].chanpos = i + 1; 
+    }
+
+    if (zt_register(&zthfc->span,0)) {
+	printk(KERN_CRIT "unable to register zaptel device!\n");
+	return -1;
+    }
+//    printk(KERN_CRIT "zaphfc: registered zaptel device!\n");
+    return 0;
+}
+
+#ifdef RTAITIMING
+#define TICK_PERIOD  1000000
+#define TICK_PERIOD2 1000000000
+#define TASK_PRIORITY 1
+#define STACK_SIZE 10000
+
+static RT_TASK rt_task;
+static struct hfc_card *rtai_hfc_list[hfc_MAX_CARDS];
+static unsigned char rtai_hfc_counter = 0;
+
+static void rtai_register_hfc(struct hfc_card *hfctmp) {
+    rtai_hfc_list[rtai_hfc_counter++] = hfctmp;
+}
+
+static void rtai_loop(int t) {
+    int i=0;
+    for (;;) {
+	for (i=0; i < rtai_hfc_counter; i++) {
+	    if (rtai_hfc_list[i] != NULL)
+		hfc_service(rtai_hfc_list[i]);
+	}
+        rt_task_wait_period();
+    }
+}
+#endif
+
+int hfc_findCards(int pcivendor, int pcidevice, char *vendor_name, char *card_name) {
+    struct pci_dev *tmp;
+    struct hfc_card *hfctmp = NULL;
+    struct zt_hfc *zthfc = NULL;
+
+    tmp = pci_find_device(pcivendor, pcidevice, multi_hfc);
+    while (tmp != NULL) {
+	multi_hfc = tmp;	// skip this next time.
+
+	if (pci_enable_device(tmp)) {
+	    multi_hfc = NULL;
+	    return -1;
+	}
+	pci_set_master(tmp);
+
+	hfctmp = kmalloc(sizeof(struct hfc_card), GFP_KERNEL);
+	if (!hfctmp) {
+	    printk(KERN_WARNING "zaphfc: unable to kmalloc!\n");
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	}
+	memset(hfctmp, 0x0, sizeof(struct hfc_card));
+	spin_lock_init(&hfctmp->lock);
+	
+	hfctmp->pcidev = tmp;
+	hfctmp->pcibus = tmp->bus->number;
+	hfctmp->pcidevfn = tmp->devfn; 
+
+	if (!tmp->irq) {
+	    printk(KERN_WARNING "zaphfc: no irq!\n");
+	} else {
+	    hfctmp->irq = tmp->irq;
+	}
+
+	hfctmp->pci_io = (char *) tmp->resource[1].start;
+	if (!hfctmp->pci_io) {
+	    printk(KERN_WARNING "zaphfc: no iomem!\n");
+	    kfree(hfctmp);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -1;
+	}
+	
+	hfctmp->fifomem = kmalloc(65536, GFP_KERNEL);
+	if (!hfctmp->fifomem) {
+	    printk(KERN_WARNING "zaphfc: unable to kmalloc fifomem!\n");
+	    kfree(hfctmp);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	} else {
+	    memset(hfctmp->fifomem, 0x0, 65536);
+	    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);
+	}
+
+#ifdef RTAITIMING
+	/* we need no stinking irq */
+	hfctmp->irq = 0;
+#else
+	if (request_irq(hfctmp->irq, &hfc_interrupt, SA_INTERRUPT | SA_SHIRQ, "zaphfc", hfctmp)) {
+	    printk(KERN_WARNING "zaphfc: unable to register irq\n");
+	    kfree(hfctmp->fifomem);
+	    kfree(hfctmp);
+	    iounmap((void *) hfctmp->pci_io);
+	    pci_disable_device(tmp);
+	    multi_hfc = NULL;
+	    return -EIO;
+	}
+#endif
+
+#ifdef RTAITIMING
+	rtai_register_hfc(hfctmp);
+#endif
+	printk(KERN_INFO
+		       "zaphfc: %s %s configured at mem %lx fifo %lx(%#x) IRQ %d HZ %d\n",
+			vendor_name, card_name,
+		       (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
+	hfctmp->regs.int_m1 = 0;	// no ints
+	hfctmp->regs.int_m2 = 0;	// not at all
+	hfc_outb(hfctmp,hfc_INT_M1,hfctmp->regs.int_m1);
+	hfc_outb(hfctmp,hfc_INT_M2,hfctmp->regs.int_m2);
+
+	if ((modes & (1 << hfc_dev_count)) != 0) {
+	    printk(KERN_INFO "zaphfc: Card %d configured for NT mode\n",hfc_dev_count);
+	    hfctmp->regs.nt_mode = 1;
+	} else {
+	    printk(KERN_INFO "zaphfc: Card %d configured for TE mode\n",hfc_dev_count);
+	    hfctmp->regs.nt_mode = 0;
+	}
+
+	zthfc = kmalloc(sizeof(struct zt_hfc),GFP_KERNEL);
+	if (!zthfc) {
+	    printk(KERN_CRIT "zaphfc: unable to kmalloc!\n");
+	    hfc_shutdownCard(hfctmp);
+	    kfree(hfctmp);
+	    multi_hfc = NULL;
+	    return -ENOMEM;
+	}
+	memset(zthfc, 0x0, sizeof(struct zt_hfc));
+
+	zthfc->card = hfctmp;
+	zthfc_initialize(zthfc);
+	hfctmp->ztdev = zthfc;
+
+	memset(hfctmp->drecbuf, 0x0, sizeof(hfctmp->drecbuf));
+	hfctmp->ztdev->chans[2].readchunk = hfctmp->drecbuf;
+
+	memset(hfctmp->dtransbuf, 0x0, sizeof(hfctmp->dtransbuf));
+	hfctmp->ztdev->chans[2].writechunk = hfctmp->dtransbuf;
+
+	memset(hfctmp->brecbuf[0], 0x0, sizeof(hfctmp->brecbuf[0]));
+	hfctmp->ztdev->chans[0].readchunk = hfctmp->brecbuf[0];
+	memset(hfctmp->btransbuf[0], 0x0, sizeof(hfctmp->btransbuf[0]));
+	hfctmp->ztdev->chans[0].writechunk = hfctmp->btransbuf[0];
+
+	memset(hfctmp->brecbuf[1], 0x0, sizeof(hfctmp->brecbuf[1]));
+	hfctmp->ztdev->chans[1].readchunk = hfctmp->brecbuf[1];
+	memset(hfctmp->btransbuf[1], 0x0, sizeof(hfctmp->btransbuf[1]));
+	hfctmp->ztdev->chans[1].writechunk = hfctmp->btransbuf[1];
+
+
+	hfc_registerCard(hfctmp);
+	hfc_resetCard(hfctmp);
+	tmp = pci_find_device(pcivendor, pcidevice, multi_hfc);
+    }
+    return 0;
+}
+
+
+
+int init_module(void) {
+    int i = 0;
+#ifdef RTAITIMING
+    RTIME tick_period;
+    for (i=0; i < hfc_MAX_CARDS; i++) {
+	rtai_hfc_list[i] = NULL;
+    }
+    rt_set_periodic_mode();
+#endif
+    i = 0;
+    while (id_list[i].vendor_id) {
+	multi_hfc = NULL;
+	hfc_findCards(id_list[i].vendor_id, id_list[i].device_id, id_list[i].vendor_name, id_list[i].card_name);
+	i++;
+    }
+#ifdef RTAITIMING
+    for (i=0; i < hfc_MAX_CARDS; i++) {
+        if (rtai_hfc_list[i]) {
+	    printk(KERN_INFO
+		       "zaphfc: configured %d at mem %#x fifo %#x(%#x) for realtime servicing\n",
+			rtai_hfc_list[i]->cardno,
+		       (u_int) rtai_hfc_list[i]->pci_io,
+		       (u_int) rtai_hfc_list[i]->fifos,
+		       (u_int) virt_to_bus(rtai_hfc_list[i]->fifos));
+
+	}
+    }
+    rt_task_init(&rt_task, rtai_loop, 1, STACK_SIZE, TASK_PRIORITY, 0, 0);
+    tick_period = start_rt_timer(nano2count(TICK_PERIOD));
+    rt_task_make_periodic(&rt_task, rt_get_time() + tick_period, tick_period);
+#endif
+    printk(KERN_INFO "zaphfc: %d hfc-pci card(s) in this box.\n", hfc_dev_count);
+    return 0;
+}
+
+void cleanup_module(void) {
+    struct hfc_card *tmpcard;
+#ifdef RTAITIMING
+    stop_rt_timer();
+    rt_task_delete(&rt_task);
+#endif
+    printk(KERN_INFO "zaphfc: stop\n");
+//    spin_lock(&registerlock);
+    while (hfc_dev_list != NULL) {
+	if (hfc_dev_list == NULL) break;
+	hfc_shutdownCard(hfc_dev_list);
+	tmpcard = hfc_dev_list;
+	hfc_dev_list = hfc_dev_list->next;
+	if (tmpcard != NULL) {
+	    kfree(tmpcard);
+	    tmpcard = NULL;
+	    printk(KERN_INFO "zaphfc: freed one card.\n");
+	}
+    }
+//    spin_unlock(&registerlock);
+}
+#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	

Added: zaptel/trunk/zaphfc/zaphfc.h
===================================================================
--- zaptel/trunk/zaphfc/zaphfc.h	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/zaphfc.h	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,289 @@
+/*
+ * zaphfc.h - Zaptel driver for HFC-S PCI A based ISDN BRI cards
+ *
+ * kernel module based on HFC PCI ISDN4Linux and Zaptel drivers
+ *
+ * Copyright (C) 2002, 2003, 2004, 2005 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.
+ *
+ */
+
+/* HFC register addresses - accessed using memory mapped I/O */
+/* For a list, see datasheet section 3.2.1 at page 21 */
+
+#define hfc_outb(a,b,c) (writeb((c),(a)->pci_io+(b)))
+#define hfc_inb(a,b) (readb((a)->pci_io+(b)))
+
+/* GCI/IOM bus monitor registers */
+
+#define hfc_C_I       0x08
+#define hfc_TRxR      0x0C
+#define hfc_MON1_D    0x28
+#define hfc_MON2_D    0x2C
+
+
+/* GCI/IOM bus timeslot registers */
+
+#define hfc_B1_SSL    0x80
+#define hfc_B2_SSL    0x84
+#define hfc_AUX1_SSL  0x88
+#define hfc_AUX2_SSL  0x8C
+#define hfc_B1_RSL    0x90
+#define hfc_B2_RSL    0x94
+#define hfc_AUX1_RSL  0x98
+#define hfc_AUX2_RSL  0x9C
+
+/* GCI/IOM bus data registers */
+
+#define hfc_B1_D      0xA0
+#define hfc_B2_D      0xA4
+#define hfc_AUX1_D    0xA8
+#define hfc_AUX2_D    0xAC
+
+/* GCI/IOM bus configuration registers */
+
+#define hfc_MST_EMOD  0xB4
+#define hfc_MST_MODE	 0xB8
+#define hfc_CONNECT 	 0xBC
+
+
+/* Interrupt and status registers */
+
+#define hfc_FIFO_EN   0x44
+#define hfc_TRM       0x48
+#define hfc_B_MODE    0x4C
+#define hfc_CHIP_ID   0x58
+#define hfc_CIRM  	 0x60
+#define hfc_CTMT	 0x64
+#define hfc_INT_M1  	 0x68
+#define hfc_INT_M2  	 0x6C
+#define hfc_INT_S1  	 0x78
+#define hfc_INT_S2  	 0x7C
+#define hfc_STATUS  	 0x70
+
+/* S/T section registers */
+
+#define hfc_STATES  	 0xC0
+#define hfc_SCTRL  	 0xC4
+#define hfc_SCTRL_E   0xC8
+#define hfc_SCTRL_R   0xCC
+#define hfc_SQ  	 0xD0
+#define hfc_CLKDEL  	 0xDC
+#define hfc_B1_REC    0xF0
+#define hfc_B1_SEND   0xF0
+#define hfc_B2_REC    0xF4
+#define hfc_B2_SEND   0xF4
+#define hfc_D_REC     0xF8
+#define hfc_D_SEND    0xF8
+#define hfc_E_REC     0xFC
+
+/* Bits and values in various HFC PCI registers */
+
+/* bits in status register (READ) */
+#define hfc_STATUS_PCI_PROC   0x02
+#define hfc_STATUS_NBUSY	  0x04 
+#define hfc_STATUS_TIMER_ELAP 0x10
+#define hfc_STATUS_STATINT	  0x20
+#define hfc_STATUS_FRAMEINT	  0x40
+#define hfc_STATUS_ANYINT	  0x80
+
+/* bits in CTMT (Write) */
+#define hfc_CTMT_CLTIMER    0x80
+#define hfc_CTMT_TIM3_125   0x04
+#define hfc_CTMT_TIM25      0x10
+#define hfc_CTMT_TIM50      0x14
+#define hfc_CTMT_TIM400     0x18
+#define hfc_CTMT_TIM800     0x1C
+#define hfc_CTMT_AUTO_TIMER 0x20
+#define hfc_CTMT_TRANSB2    0x02
+#define hfc_CTMT_TRANSB1    0x01
+
+/* bits in CIRM (Write) */
+#define hfc_CIRM_AUX_MSK    0x07
+#define hfc_CIRM_RESET  	  0x08
+#define hfc_CIRM_B1_REV     0x40
+#define hfc_CIRM_B2_REV     0x80
+
+/* bits in INT_M1 and INT_S1 */
+#define hfc_INTS_B1TRANS  0x01
+#define hfc_INTS_B2TRANS  0x02
+#define hfc_INTS_DTRANS   0x04
+#define hfc_INTS_B1REC    0x08
+#define hfc_INTS_B2REC    0x10
+#define hfc_INTS_DREC     0x20
+#define hfc_INTS_L1STATE  0x40
+#define hfc_INTS_TIMER    0x80
+
+/* bits in INT_M2 */
+#define hfc_M2_PROC_TRANS    0x01
+#define hfc_M2_GCI_I_CHG     0x02
+#define hfc_M2_GCI_MON_REC   0x04
+#define hfc_M2_IRQ_ENABLE    0x08
+#define hfc_M2_PMESEL        0x80
+
+/* bits in STATES */
+#define hfc_STATES_STATE_MASK     0x0F
+#define hfc_STATES_LOAD_STATE    0x10
+#define hfc_STATES_ACTIVATE	     0x20
+#define hfc_STATES_DO_ACTION     0x40
+#define hfc_STATES_NT_G2_G3      0x80
+
+/* bits in HFCD_MST_MODE */
+#define hfc_MST_MODE_MASTER	     0x01
+#define hfc_MST_MODE_SLAVE         0x00
+/* remaining bits are for codecs control */
+
+/* bits in HFCD_SCTRL */
+#define hfc_SCTRL_B1_ENA	     0x01
+#define hfc_SCTRL_B2_ENA	     0x02
+#define hfc_SCTRL_MODE_TE        0x00
+#define hfc_SCTRL_MODE_NT        0x04
+#define hfc_SCTRL_LOW_PRIO	     0x08
+#define hfc_SCTRL_SQ_ENA	     0x10
+#define hfc_SCTRL_TEST	     0x20
+#define hfc_SCTRL_NONE_CAP	     0x40
+#define hfc_SCTRL_PWR_DOWN	     0x80
+
+/* bits in SCTRL_E  */
+#define hfc_SCTRL_E_AUTO_AWAKE    0x01
+#define hfc_SCTRL_E_DBIT_1        0x04
+#define hfc_SCTRL_E_IGNORE_COL    0x08
+#define hfc_SCTRL_E_CHG_B1_B2     0x80
+
+/* bits in FIFO_EN register */
+#define hfc_FIFOEN_B1TX   0x01
+#define hfc_FIFOEN_B1RX   0x02
+#define hfc_FIFOEN_B2TX   0x04
+#define hfc_FIFOEN_B2RX   0x08
+#define hfc_FIFOEN_DTX    0x10
+#define hfc_FIFOEN_DRX    0x20
+
+#define hfc_FIFOEN_B1     (hfc_FIFOEN_B1TX|hfc_FIFOEN_B1RX)
+#define hfc_FIFOEN_B2     (hfc_FIFOEN_B2TX|hfc_FIFOEN_B2RX)
+#define hfc_FIFOEN_D      (hfc_FIFOEN_DTX|hfc_FIFOEN_DRX)
+
+/* bits in the CONNECT register */
+#define hfc_CONNECT_B1_shift	0
+#define hfc_CONNECT_B2_shift	3
+
+#define	hfc_CONNECT_HFC_from_ST		0x0
+#define hfc_CONNECT_HFC_from_GCI	0x1
+#define hfc_CONNECT_ST_from_HFC		0x0
+#define hfc_CONNECT_ST_from_GCI		0x2
+#define hfc_CONNECT_GCI_from_HFC	0x0
+#define	hfc_CONNECT_GCI_from_ST		0x4
+
+/* bits in the __SSL and __RSL registers */
+#define	hfc_SRSL_STIO	0x40
+#define hfc_SRSL_ENABLE	0x80
+#define hfc_SRCL_SLOT_MASK	0x1f
+
+/* FIFO memory definitions */
+
+#define hfc_FMASK	0x000f
+#define hfc_ZMASK	0x01ff
+#define hfc_ZMASKB	0x1fff
+
+#define hfc_D_FIFO_SIZE	0x0200
+#define hfc_B_SUB_VAL	0x0200
+#define hfc_B_FIFO_SIZE	0x1E00
+#define hfc_MAX_DFRAMES	0x000f
+
+#define hfc_FIFO_DTX_Z1	0x2080
+#define hfc_FIFO_DTX_Z2 0x2082
+#define hfc_FIFO_DTX_F1	0x20a0
+#define hfc_FIFO_DTX_F2	0x20a1
+#define hfc_FIFO_DTX	0x0000
+#define hfc_FIFO_DTX_ZOFF	0x000
+
+#define hfc_FIFO_DRX_Z1	0x6080
+#define hfc_FIFO_DRX_Z2 0x6082
+#define hfc_FIFO_DRX_F1	0x60a0
+#define hfc_FIFO_DRX_F2	0x60a1
+#define hfc_FIFO_DRX	0x4000
+#define hfc_FIFO_DRX_ZOFF	0x4000
+
+#define hfc_FIFO_B1TX_Z1	0x2000
+#define hfc_FIFO_B1TX_Z2 	0x2002
+#define hfc_FIFO_B1RX_Z1	0x6000
+#define hfc_FIFO_B1RX_Z2 	0x6002
+
+#define hfc_FIFO_B1TX_F1	0x2080
+#define hfc_FIFO_B1TX_F2	0x2081
+#define hfc_FIFO_B1RX_F1	0x6080
+#define hfc_FIFO_B1RX_F2	0x6081
+
+#define hfc_FIFO_B1RX_ZOFF	0x4000
+#define hfc_FIFO_B1TX_ZOFF	0x0000
+
+#define hfc_FIFO_B2TX_Z1	0x2100
+#define hfc_FIFO_B2TX_Z2 	0x2102
+#define hfc_FIFO_B2RX_Z1	0x6100
+#define hfc_FIFO_B2RX_Z2 	0x6102
+
+#define hfc_FIFO_B2TX_F1	0x2180
+#define hfc_FIFO_B2TX_F2	0x2181
+#define hfc_FIFO_B2RX_F1	0x6180
+#define hfc_FIFO_B2RX_F2	0x6181
+
+#define hfc_FIFO_B2RX_ZOFF	0x6000
+#define hfc_FIFO_B2TX_ZOFF	0x2000
+
+#define hfc_BTRANS_THRESHOLD 128
+#define hfc_BTRANS_THRESMASK 0x00
+
+/* Structures */
+
+typedef struct hfc_regs {
+    unsigned char fifo_en;
+    unsigned char ctmt;
+    unsigned char int_m1;
+    unsigned char int_m2;
+    unsigned char sctrl;
+    unsigned char sctrl_e;
+    unsigned char sctrl_r;
+    unsigned char connect;
+    unsigned char trm;
+    unsigned char mst_mode;
+    unsigned char bswapped;
+    unsigned char nt_mode;
+    unsigned char int_drec;
+} hfc_regs;
+
+typedef struct hfc_card {
+    spinlock_t lock;
+    unsigned int irq;
+    unsigned int iomem;
+    int ticks;		
+    int clicks;		
+    unsigned char *pci_io;
+    void *fifomem;		// start of the shared mem
+    volatile void *fifos;	// 32k aligned mem for the fifos
+    struct hfc_regs regs;
+    unsigned int pcibus;
+    unsigned int pcidevfn;
+    struct pci_dev *pcidev;
+    struct zt_hfc *ztdev;
+    int	drecinframe;
+    unsigned char drecbuf[hfc_D_FIFO_SIZE];
+    unsigned char dtransbuf[hfc_D_FIFO_SIZE];
+    unsigned char brecbuf[2][ZT_CHUNKSIZE];
+    unsigned char btransbuf[2][ZT_CHUNKSIZE];
+    unsigned char cardno;
+    struct hfc_card *next;
+} hfc_card;
+
+typedef struct zt_hfc {
+    unsigned int usecount;
+    struct zt_span span;
+    struct zt_chan chans[3];
+    struct hfc_card *card;
+} zt_hfc;
+
+/* tune this */
+#define hfc_BCHAN_BUFFER	8
+#define hfc_MAX_CARDS		8

Added: zaptel/trunk/zaphfc/zaptel.conf
===================================================================
--- zaptel/trunk/zaphfc/zaptel.conf	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/zaphfc/zaptel.conf	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,8 @@
+# hfc-s pci a span definition
+# most of the values should be bogus because we are not really zaptel
+loadzone=nl
+defaultzone=nl
+
+span=1,1,3,ccs,ami
+bchan=1-2
+dchan=3

Added: zaptel/trunk/ztgsm/LICENSE
===================================================================
--- zaptel/trunk/ztgsm/LICENSE	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/LICENSE	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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.

Added: zaptel/trunk/ztgsm/Makefile
===================================================================
--- zaptel/trunk/ztgsm/Makefile	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/Makefile	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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

Added: zaptel/trunk/ztgsm/TODO
===================================================================

Added: zaptel/trunk/ztgsm/zapata.conf.duoGSM
===================================================================
--- zaptel/trunk/ztgsm/zapata.conf.duoGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zapata.conf.duoGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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
+

Added: zaptel/trunk/ztgsm/zapata.conf.quadGSM
===================================================================
--- zaptel/trunk/ztgsm/zapata.conf.quadGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zapata.conf.quadGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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

Added: zaptel/trunk/ztgsm/zapata.conf.unoGSM
===================================================================
--- zaptel/trunk/ztgsm/zapata.conf.unoGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zapata.conf.unoGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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

Added: zaptel/trunk/ztgsm/zaptel.conf.duoGSM
===================================================================
--- zaptel/trunk/ztgsm/zaptel.conf.duoGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zaptel.conf.duoGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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
+

Added: zaptel/trunk/ztgsm/zaptel.conf.quadGSM
===================================================================
--- zaptel/trunk/ztgsm/zaptel.conf.quadGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zaptel.conf.quadGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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
+

Added: zaptel/trunk/ztgsm/zaptel.conf.unoGSM
===================================================================
--- zaptel/trunk/ztgsm/zaptel.conf.unoGSM	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/zaptel.conf.unoGSM	2006-06-19 20:27:22 UTC (rev 1918)
@@ -0,0 +1,10 @@
+loadzone=nl
+defaultzone=nl
+
+alaw=1
+
+span=1,1,3,ccs,ami
+
+bchan=1
+dchan=2
+

Added: zaptel/trunk/ztgsm/ztgsm.c
===================================================================
--- zaptel/trunk/ztgsm/ztgsm.c	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/ztgsm.c	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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	

Added: zaptel/trunk/ztgsm/ztgsm.h
===================================================================
--- zaptel/trunk/ztgsm/ztgsm.h	2006-06-19 13:21:24 UTC (rev 1917)
+++ zaptel/trunk/ztgsm/ztgsm.h	2006-06-19 20:27:22 UTC (rev 1918)
@@ -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)
+
+




More information about the Pkg-voip-commits mailing list