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

Tzafrir Cohen tzafrir-guest at alioth.debian.org
Sat Feb 10 03:19:37 CET 2007


Author: tzafrir-guest
Date: 2007-02-10 03:19:35 +0100 (Sat, 10 Feb 2007)
New Revision: 3127

Added:
   zaptel/trunk/xpp/
   zaptel/trunk/xpp/card_bri.c
   zaptel/trunk/xpp/card_bri.h
Removed:
   zaptel/trunk/debian/patches/xpp_udev.dpatch
Modified:
   zaptel/trunk/debian/changelog
   zaptel/trunk/debian/patches/00list
   zaptel/trunk/debian/patches/Makefile_bristuff.dpatch
   zaptel/trunk/debian/patches/Makefile_deps_utils.dpatch
   zaptel/trunk/debian/patches/Makefile_hostcc.dpatch
   zaptel/trunk/debian/patches/Makefile_targets.dpatch
   zaptel/trunk/debian/patches/Makefile_uname.dpatch
   zaptel/trunk/debian/patches/Makefile_vzaphfc.dpatch
   zaptel/trunk/debian/patches/bristuff.dpatch
   zaptel/trunk/debian/patches/ukcid.dpatch
   zaptel/trunk/debian/patches/xpp_all_platforms.dpatch
   zaptel/trunk/debian/rules
Log:
* New upstream release: 1.2.13 .
* Fixed firmware stripping rules.
* ukcid, bristuff: renames zaptel.c to zaptel-base.c.
* Makefile_bridtuff.dpatch: moved patch to void collision.
* Adjusted Makefile patches to new version.
* wct4xxp-dfsg.dpatch: disabled until rewritten.
* xpp_udev.dpatch: removed as it is now applied upstream.
* Add Makefile.kernel26 and wctc4xxp/ to source tarball.
* Adding xpp/card_bri.[ch] that were left out of the Digium commit for
  some reasons.


Modified: zaptel/trunk/debian/changelog
===================================================================
--- zaptel/trunk/debian/changelog	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/changelog	2007-02-10 02:19:35 UTC (rev 3127)
@@ -1,3 +1,18 @@
+zaptel (1:1.2.13~dfsg-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+  * Fixed firmware stripping rules.
+  * ukcid, bristuff: renames zaptel.c to zaptel-base.c.
+  * Makefile_bridtuff.dpatch: moved patch to void collision.
+  * Adjusted Makefile patches to new version.
+  * wct4xxp-dfsg.dpatch: disabled until rewritten.
+  * xpp_udev.dpatch: removed as it is now applied upstream.
+  * Add Makefile.kernel26 and wctc4xxp/ to source tarball.
+  * Adding xpp/card_bri.[ch] that were left out of the Digium commit for
+    some reasons.
+
+ -- Tzafrir Cohen <tzafrir.cohen at xorcom.com>  Fri,  9 Feb 2007 21:58:37 +0200
+
 zaptel (1:1.2.12~dfsg-4) UNRELEASED; urgency=low
 
   [Tzafrir Cohen]

Modified: zaptel/trunk/debian/patches/00list
===================================================================
--- zaptel/trunk/debian/patches/00list	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/00list	2007-02-10 02:19:35 UTC (rev 3127)
@@ -11,8 +11,7 @@
 bristuff_local_zaptelh
 Makefile_vzaphfc.dpatch
 ztpty_ioctl_warn
-wct4xxp-dfsg.dpatch
+#wct4xxp-dfsg.dpatch
 dbug391840.dpatch
 Makefile_hostcc
-xpp_udev
 xpp_all_platforms

Modified: zaptel/trunk/debian/patches/Makefile_bristuff.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_bristuff.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_bristuff.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -30,10 +30,11 @@
  all: modules $(LIBTONEZONE_SO)
  
  programs: $(BINS) $(LIBTONEZONE_SO)
-@@ -209,6 +216,28 @@
+@@ -209,6 +216,29 @@
+ wctdm24xxp.o: wctdm.h
  
- ztdummy.o: ztdummy.h
- 
+ pciradio.o: radfw.h
++
 +$(BRIMODS:%=%.o): %.o: %.h
 +ifneq (,$(wildcard /usr/src/modules/rtai/base/include/rtai.h))
 +zaphfc.o: KFLAGS+=-DRTAITIMING \
@@ -56,6 +57,6 @@
 +cwain.%: cwain/cwain.%
 +	cp $^ $@
 +
- $(MODULESO): %.o: %.c zaptel.h
- 	$(CC) $(KFLAGS) -o $@ -c $<
  
+ ztdummy.o: ztdummy.h
+ 

Modified: zaptel/trunk/debian/patches/Makefile_deps_utils.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_deps_utils.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_deps_utils.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -10,17 +10,17 @@
 --- zaptel-1.2.0-0beta1/Makefile	2005-09-10 17:14:59.442470186 +0300
 +++ /tmp/dpep.GxuAYU/zaptel-1.2.0-0beta1/Makefile	2005-09-10 18:43:28.224686623 +0300
 @@ -109,7 +109,10 @@
- ifneq (,$(wildcard /usr/include/newt.h))
- ZTTOOL:=zttool
- endif
--BINS=ztcfg torisatool makefw ztmonitor ztspeed $(ZTTOOL) zttest fxotune
-+BINS:=ztcfg ztmonitor ztspeed $(ZTTOOL) zttest fxotune
+ 
+ MOD_DESTDIR:=zaptel
+ 
+-BINS=ztcfg torisatool makefw ztmonitor ztspeed zttest fxotune
++BINS=ztcfg ztmonitor ztspeed zttest fxotune
 +UTILS:=tor2ee ztspeed zttool ztmonitor sethdlc-new \
 +  usbfxstest fxstest fxotune fxsdump ztdiag
 +UTILSO:=$(UTILS:%=%.o)
- 
- #PRIMARY=wcfxsusb
- PRIMARY=torisa
+ ifneq (,$(wildcard /usr/include/newt.h))
+ BINS+=zttool
+ endif
 @@ -173,8 +176,7 @@
  
  tor2ee.o: tor2-hw.h

Modified: zaptel/trunk/debian/patches/Makefile_hostcc.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_hostcc.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_hostcc.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -9,10 +9,10 @@
 --- zaptel-1.2.12~dfsg~/Makefile	2006-12-07 00:22:11.000000000 +0100
 +++ zaptel-1.2.12~dfsg/Makefile	2006-12-28 13:17:04.396969151 +0100
 @@ -6,7 +6,6 @@
- #
  
+ else
  
 -HOSTCC=gcc
- PWD:=$(shell pwd)
  
  INSTALL_PREFIX:=$(DESTDIR)
+ 

Modified: zaptel/trunk/debian/patches/Makefile_targets.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_targets.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_targets.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -7,11 +7,11 @@
 ## -- will be fixed later on.. still pending.
 
 @DPATCH@
-diff -urNad zaptel-1.2.1/Makefile /tmp/dpep.hnX6Yg/zaptel-1.2.1/Makefile
---- zaptel-1.2.1/Makefile	2005-12-22 00:01:06.000000000 +0200
-+++ /tmp/dpep.hnX6Yg/zaptel-1.2.1/Makefile	2005-12-22 00:09:25.000000000 +0200
-@@ -122,6 +122,16 @@
- endif
+diff -urNad zaptel-1.2.13~dfsg~/Makefile zaptel-1.2.13~dfsg/Makefile
+--- zaptel-1.2.13~dfsg~/Makefile	2007-02-10 00:59:31.000000000 +0200
++++ zaptel-1.2.13~dfsg/Makefile	2007-02-10 01:09:53.000000000 +0200
+@@ -64,6 +64,16 @@
+ 
  MODULESO:=$(MODULES:%=%.o)
  MODULESKO:=$(MODULES:%=%.ko)
 +ifeq ($(BUILDVER),linux26)
@@ -25,23 +25,34 @@
 +INC_DIR:=$(INSTALL_PREFIX)/usr/include
 +MOD_DIR:=$(INSTALL_PREFIX)/lib/modules/$(KVERS)/misc
  
- ifneq (,$(wildcard /usr/include/newt.h))
- ZTTOOL:=zttool
-@@ -136,7 +146,11 @@
- #PRIMARY=wcfxo
- PWD:=$(shell pwd)
+ # add this later, so it doesn't become part of MODULESO/MODULESKO
+ MODULES+=wct4xxp wctc4xxp
+@@ -161,15 +171,17 @@
+ BINS+=zttool
+ endif
  
--all: $(BUILDVER) $(LIBTONEZONE_SO)
+-ifeq ($(BUILDVER),linux24)
+-all: prereq $(MODULESO) wct4xxp/wct4xxp.o $(BINS) $(LIBTONEZONE_SO)
+-endif
 +all: modules $(LIBTONEZONE_SO)
-+
+ 
+-ifeq ($(BUILDVER),linux26)
+-all: prereq $(BINS) $(LIBTONEZONE_SO)
 +programs: $(BINS) $(LIBTONEZONE_SO)
 +
 +modules: $(BUILDVER)
++
++linux24: $(MODULESO) wct4xxp/wct4xxp.o
++
++linux26: prereq $(BINS) $(LIBTONEZONE_SO)
+ 	@if [ -z "$(KSRC)" -o ! -d "$(KSRC)" ]; then echo "You do not appear to have the sources for the $(KVERS) kernel installed."; exit 1 ; fi
+ 	$(MAKE) -C $(KSRC) SUBDIRS=$(PWD) HOTPLUG_FIRMWARE=$(HOTPLUG_FIRMWARE) modules
+-endif
  
- linux24: $(MODULESO) $(BINS)
- 
-@@ -387,6 +401,21 @@
- 		echo "Not under version control"; \
+ ifeq ($(HPEC_PRESENT),yes)
+ ifeq ($(ARCH),i386)
+@@ -430,6 +442,21 @@
+ 		echo "Not under version control";  \
  	fi
  
 +# make should *fail* and not silently succeed if a program did not build
@@ -61,4 +72,4 @@
 +
  clean:
  	rm -f torisatool makefw tor2fw.h radfw.h
- 	rm -f ${BINS}
+ 	rm -f $(BINS)

Modified: zaptel/trunk/debian/patches/Makefile_uname.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_uname.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_uname.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -8,12 +8,12 @@
 ## DP: no. 2.6.2-4) and will also consider 2.5 as linux26 BUILDVER .
 
 @DPATCH@
-diff -urNad zaptel-1.2.11.dfsg~/Makefile zaptel-1.2.11.dfsg/Makefile
---- zaptel-1.2.11.dfsg~/Makefile	2006-12-02 14:12:47.000000000 +0000
-+++ zaptel-1.2.11.dfsg/Makefile	2006-12-02 14:12:54.000000000 +0000
-@@ -11,6 +11,11 @@
+diff -urNad zaptel-1.2.13~dfsg~/Makefile zaptel-1.2.13~dfsg/Makefile
+--- zaptel-1.2.13~dfsg~/Makefile	2007-02-09 23:27:13.000000000 +0200
++++ zaptel-1.2.13~dfsg/Makefile	2007-02-10 00:01:10.000000000 +0200
+@@ -13,6 +13,11 @@
  
- INSTALL_PREFIX:=$(DESTDIR)
+ ARCH:=$(shell uname -m | sed -e s/i.86/i386/)
  
 +ifeq ($(DEB_HOST_GNU_TYPE),)
 +UNAME_M:=$(shell uname -m)
@@ -23,17 +23,14 @@
  # If you want to build for a kernel other than the current kernel, set KVERS
  ifndef KVERS
  KVERS:=$(shell uname -r)
-@@ -23,11 +28,16 @@
-     KSRC:=$(shell for dir in $(KSRC_SEARCH_PATH); do if [ -d $$dir ]; then echo $$dir; break; fi; done)
-   endif
- endif
-+KVERS_MAJ:=$(shell echo $(KVERS) | cut -d. -f1-2)
- KINCLUDES:=$(KSRC)/include
+@@ -89,20 +95,28 @@
  
--CFLAGS+=-I. -O4 -g -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER
+ INSTALL_PREFIX:=$(DESTDIR)
+ 
+-CFLAGS+=-I. -O4 -g -Wall
 -CFLAGS_PPC:=$(shell if uname -m | grep -q ppc; then echo "-fsigned-char"; fi)
 -CFLAGS_X86-64:=$(shell if uname -m | grep -q x86_64; then echo "-m64"; fi)
-+CFLAGS+=-I. -O2 -g -Wall -DBUILDING_TONEZONE #-DTONEZONE_DRIVER
++CFLAGS+=-I. -O2 -g -Wall
 +ifneq (,$(findstring ppc,$(UNAME_M)))
 +CFLAGS_PPC:=-fsigned-char
 +endif
@@ -42,8 +39,10 @@
 +endif
  CFLAGS+=$(CFLAGS_PPC) $(CFLAGS_X86-64)
  LCFLAGS:=-fPIC $(CFLAGS) -DBUILDING_TONEZONE
- KFLAGS:=-I$(KINCLUDES) -O6
-@@ -36,9 +46,15 @@
+-KFLAGS:=-I$(KINCLUDES) -O6
++KFLAGS:=-I$(KINCLUDES) -O2
+ KFLAGS+=-DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -I$(KSRC)/drivers/net \
+ 	-Wall -I. -Wstrict-prototypes -fomit-frame-pointer -I$(KSRC)/drivers/net/wan -I$(KINCLUDES)/net
  ifneq (,$(wildcard $(KINCLUDES)/linux/modversions.h))
    KFLAGS+=-DMODVERSIONS -include $(KINCLUDES)/linux/modversions.h
  endif
@@ -53,25 +52,9 @@
 +endif
  KFLAGS+=$(KFLAGS_PPC)
 -KFLAGS+=$(shell if uname -r | grep -q 2.4; then if uname -m | grep -q x86_64; then echo "-mcmodel=kernel"; fi; fi)
-+ifeq ($(KVERS_MAJ),2.4)
-+  ifneq (,$(findstring x86_64,$(UNAME_M)))
-+    KFLAGS+=-mcmodel=kernel
-+  endif
++ifneq (,$(findstring x86_64,$(UNAME_M)))
++  KFLAGS+=-mcmodel=kernel
 +endif
  
  #
  # Features are now configured in zconfig.h
-@@ -52,10 +68,10 @@
- CONFIG_FILE:=$(INSTALL_PREFIX)/etc/zaptel.conf
- CFLAGS+=-DZAPTEL_CONFIG=\"$(CONFIG_FILE)\"
- 
--ifeq (2.6,$(shell echo $(KVERS) | cut -d. -f1-2))
--  BUILDVER:=linux26
--else
-+ifeq ($(KVERS_MAJ),2.4)
-   BUILDVER:=linux24
-+else
-+  BUILDVER:=linux26
- endif
- 
- ifeq ($(BUILDVER),linux24)

Modified: zaptel/trunk/debian/patches/Makefile_vzaphfc.dpatch
===================================================================
--- zaptel/trunk/debian/patches/Makefile_vzaphfc.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/Makefile_vzaphfc.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -5,16 +5,13 @@
 ## DP: Add vzaphfc to linux-2.6 modules
 
 @DPATCH@
-diff -urNad zaptel-1.2.12~dfsg~/Makefile zaptel-1.2.12~dfsg/Makefile
---- zaptel-1.2.12~dfsg~/Makefile	2006-12-27 20:59:12.564324230 +0100
-+++ zaptel-1.2.12~dfsg/Makefile	2006-12-27 22:48:51.929450581 +0100
-@@ -150,7 +150,8 @@
+diff -urNad zaptel-1.2.13~dfsg~/Makefile.kernel26 zaptel-1.2.13~dfsg/Makefile.kernel26
+--- zaptel-1.2.13~dfsg~/Makefile.kernel26	2007-02-08 20:13:41.000000000 +0200
++++ zaptel-1.2.13~dfsg/Makefile.kernel26	2007-02-10 02:58:58.000000000 +0200
+@@ -1,5 +1,6 @@
+ obj-m := $(MODULESO)
+ obj-m += wct4xxp/ wctc4xxp/
++obj-m += vzaphfc/
  
- obj-m:=$(MODULESO)
- obj-m+=wct4xxp/
--MODULES+=wct4xxp
-+obj-m+=vzaphfc/
-+MODULES+=wct4xxp vzaphfc
- 
- # Also build xpp in the subdirectory xpp/ . But only for >=2.6.10 and only 
- # for i386. On other archs the module will probably build but panic.
+ # Also build xpp in the subdirectory xpp/ . But only for >=2.6.8 and only 
+ # for i386 or x86_64. On other platforms it has still not been tested well 

Modified: zaptel/trunk/debian/patches/bristuff.dpatch
===================================================================
--- zaptel/trunk/debian/patches/bristuff.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/bristuff.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -7,8 +7,8 @@
 
 @DPATCH@
 diff -urN zaptel-1.2.10.orig/zaptel.c zaptel-1.2.10/zaptel.c
---- zaptel-1.2.10.orig/zaptel.c	2006-09-16 09:45:04.000000000 +0200
-+++ zaptel-1.2.10/zaptel.c	2006-12-20 17:59:51.000000000 +0100
+--- zaptel-1.2.10.orig/zaptel-base.c	2006-09-16 09:45:04.000000000 +0200
++++ zaptel-1.2.10/zaptel-base.c	2006-12-20 17:59:51.000000000 +0100
 @@ -139,6 +139,7 @@
  EXPORT_SYMBOL(zt_qevent_lock);
  EXPORT_SYMBOL(zt_hooksig);

Modified: zaptel/trunk/debian/patches/ukcid.dpatch
===================================================================
--- zaptel/trunk/debian/patches/ukcid.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/ukcid.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -7,8 +7,8 @@
 
 @DPATCH@
 diff -urNad zaptel-1.1.9.0beta2/zaptel.c /tmp/dpep.qnDT2q/zaptel-1.1.9.0beta2/zaptel.c
---- zaptel-1.1.9.0beta2/zaptel.c	2005-10-04 23:34:36.000000000 +0300
-+++ /tmp/dpep.qnDT2q/zaptel-1.1.9.0beta2/zaptel.c	2005-11-01 23:37:26.435046197 +0200
+--- zaptel-1.1.9.0beta2/zaptel-base.c	2005-10-04 23:34:36.000000000 +0300
++++ /tmp/dpep.qnDT2q/zaptel-1.1.9.0beta2/zaptel-base.c	2005-11-01 23:37:26.435046197 +0200
 @@ -734,6 +734,20 @@
  	unsigned char *newbuf, *oldbuf;
  	unsigned long flags;
@@ -39,7 +39,7 @@
  	int ret;
  	int oldconf;
  	void *rxgain=NULL;
- 	echo_can_state_t *ec, *tec;
+ 	struct echo_can_state *ec, *tec;
 +	struct zt_history hist;
  
  	if (!chan)

Modified: zaptel/trunk/debian/patches/xpp_all_platforms.dpatch
===================================================================
--- zaptel/trunk/debian/patches/xpp_all_platforms.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/xpp_all_platforms.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -4,19 +4,24 @@
 ## All lines beginning with `## DP:' are a description of the patch.
 ## DP: Build the xpp/ subdirectory on all platforms.
 ## DP: Does not remove misleading text as to not conflict with Makefile_zaphfc
-## DP: Applied by upstream in 1.4 .
+## DP: Applied by upstream in trunk.
 
 @DPATCH@
-diff -urNad zaptel-1.2.12~dfsg~/Makefile zaptel-1.2.12~dfsg/Makefile
---- zaptel-1.2.12~dfsg~/Makefile	2007-01-20 22:27:28.000000000 +0200
-+++ zaptel-1.2.12~dfsg/Makefile	2007-01-20 22:27:42.000000000 +0200
-@@ -126,9 +126,7 @@
- # This line is only meaningful when this Makefile is used as kconfig for 
- # 2.6 build
- 
--ifneq (,$(shell [ 0$(SUBLEVEL) -ge 10 ] && [ "$(ARCH)" = 'i386' ] && echo 1))
+diff -urNad zaptel-1.2.12~dfsg~/Makefile.kernel26 zaptel-1.2.12~dfsg/Makefile.kernel26
+--- zaptel-1.2.12~dfsg~/Makefile.kernel26	2007-01-20 22:27:28.000000000 +0200
++++ zaptel-1.2.12~dfsg/Makefile.kernel26	2007-01-20 22:27:42.000000000 +0200
+@@ -5,14 +5,7 @@
+ # Also build xpp in the subdirectory xpp/ . But only for >=2.6.8 and only 
+ # for i386 or x86_64. On other platforms it has still not been tested well 
+ # enough.
+-ifneq (,$(shell [ 0$(SUBLEVEL) -ge 8 ] && echo 1))
+-ifeq ($(ARCH),i386)
  obj-m+=xpp/
 -endif
+-ifeq ($(ARCH),x86_64)
+-obj-m+=xpp/
+-endif
+-endif
  
- ifneq (,$(wildcard /usr/include/newt.h))
- ZTTOOL:=zttool
+ EXTRA_CFLAGS := -I$(src)
+ 

Deleted: zaptel/trunk/debian/patches/xpp_udev.dpatch
===================================================================
--- zaptel/trunk/debian/patches/xpp_udev.dpatch	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/patches/xpp_udev.dpatch	2007-02-10 02:19:35 UTC (rev 3127)
@@ -1,200 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## xpp_udev.dpatch by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Fix udev firmware load (and slight documentation) of the Xorcom 
-## DP: Astribank (zaptel/xpp)
-## DP: Patch is to be merged soon into official driver.
-
- at DPATCH@
-diff -urNad zaptel-1.2.12~dfsg~/xpp/README.Astribank zaptel-1.2.12~dfsg/xpp/README.Astribank
---- zaptel-1.2.12~dfsg~/xpp/README.Astribank	2006-11-30 23:46:11.000000000 +0200
-+++ zaptel-1.2.12~dfsg/xpp/README.Astribank	2007-01-08 16:05:37.000000000 +0200
-@@ -126,11 +126,54 @@
- this will be the old value + 1.
- 
- 
-+Firmware Loading with Hotplug:
-+"""""""""""""""""""""""""""""
-+The Hotplug framework was popular for hotplugging and usually also 
-+autoloading drivers. If it is used on your system, you'll see 
-+/etc/hotplug with many files under it. Hotplug will automatically load
-+most relevant USB and PCI kernel modules by the relevant USB and PCI
-+IDs. Again: if the framework is in place and the proper configuration
-+files are in place, the firmware should be loaded automatically.
-+
-+In order to get hotplug to autoload the firmware into the Astribank, 
-+the configuration file xpp_fxloader.usermap and the script xpp_fxloader 
-+should be copied into /etc/hotplug/usb/ . This is done by 'make -C
-+xpp/utils install' .
-+
-+xpp_fxloader.usermap includes a map of USB IDs and the command to run 
-+when they are encountered. It instructs hotplug to run the script 
-+xpp_fxloader from that directory. This is done by 'make -C
-+xpp/utils install' .
-+
-+When xpp_fxloader is run without any parameters it assumes that it was
-+run by the hotplug scripts. It will then check if the even is an "add"
-+event (and not a "remove" event), and if so, install the required
-+firmware file. It will be called twice, as after the load of the USB
-+firmware the device will reenumerate itself and thus "unplug" and
-+"replug" to load the FPGA firmware.
-+
-+
- Firmware Loading with UDEV:
- """"""""""""""""""""""""""
--Firmware loading with udev should work but is not installed 
--automatically, yet. See the comments in the beginning of the script
--/etc/hotplug/usb/xpp_fxloader .
-+The UDEV framework has replaced Hotplug in most recent systems. If you
-+have a recent 2.6 system with no Hotplug and files under /etc/udev,
-+chances are you ude udev. udev does quite a few nice things.
-+Again: if the framework is in place and the proper configuration
-+files are in place, the firmware should be loaded automatically.
-+
-+In order to get hotplug to autoload the firmware into the Astribank, 
-+the configuration file xpp.rules should be copied into /etc/udev/rules.d 
-+and the script xpp_fxloader should be copied into /etc/hotplug/usb/ . 
-+This is done by 'make -C xpp/utils install' .
-+
-+xpp.rules instructs udevd to run xpp_fxloader with the option udev and
-+the USB ID when an Astribank is plugged and needs loading firmware.
-+When xpp_fxloader is run with the option udev it assumes that it was
-+run by udevd scripts. It will then install the required firmware file. 
-+It will be called twice, as after the load of the USB firmware the
-+device will reenumerate itself and thus "unplug" and "replug" to load 
-+the FPGA firmware.
-+
- 
- Loading The Modules:
- """""""""""""""""""
-@@ -297,6 +340,47 @@
-           13 XPP_IN/0-12 FXOKS (In use) 
-           14 XPP_IN/0-13 FXOKS (In use) 
- 
-+Sample dialplan (extentions.conf) for all the above:
-+
-+[phones-zap] 
-+; 401 will dial to channel 1, 420, to zaptel channel 20, etc. 
-+exten => _4XX,1,Dial(ZAP/${EXTEN:1}) 
-+ 
-+[trunk-9] 
-+; Dial through the first FXO port availble.  
-+; This assumes that all FXO ports are in group 0 and all others are not,  
-+; as in the sample zapata.conf for 8FXS/8FXO below, and as is generated 
-+; by genzaptelconf by default. 
-+exten => 9.,Dial(Zap/g0/${EXTEN:1}) 
-+ 
-+[from-internal] 
-+;  The context of FXS ports: analog phones.  
-+; They are allowed to dial to all other phones 
-+include => phones-zap 
-+; They are also allowed to call through the trunk: 
-+include => trunk-9 
-+ 
-+[from-pstn] 
-+; Calls from the PSTN enter here. Redirect calls to an IVR 
-+; or a default extension in the s context here. In this case we  
-+; redirect calls to Zaptel channel 1: 
-+exten => s,1,Dial(Zap/1) 
-+ 
-+[astribank-inputs] 
-+exten => s,1,Set(ZAP_CHAN=Cut(${CHANNEL},-,1)) 
-+exten => s,n,Set(ZAP_CHAN=Cut(${ZAP_CHAN},/,2)) 
-+; 11 is the number of the first input port. At least in the sample 
-+; configuration below. 
-+exten => s,n,Set(INPUT_NUM=Math(${ZAP_CHAN}-11)) 
-+; The sample below just logs the signal.  
-+exten => s,n,NoOp(Got signal from input port number ${INPUT_NUM}) 
-+; Alternatively: 
-+;exten => s,n,System(run something) 
-+ 
-+; No. We did not forget the context astribank-outputs. Output 
-+; ports only get calls from the PBX. Thus they don't need a context 
-+; of their own. 
-+
- 
- /proc Interface
- """""""""""""""
-diff -urNad zaptel-1.2.12~dfsg~/xpp/utils/Makefile zaptel-1.2.12~dfsg/xpp/utils/Makefile
---- zaptel-1.2.12~dfsg~/xpp/utils/Makefile	2006-11-30 23:46:11.000000000 +0200
-+++ zaptel-1.2.12~dfsg/xpp/utils/Makefile	2007-01-08 16:05:37.000000000 +0200
-@@ -16,6 +16,7 @@
- DATADIR   = $(datadir)/zaptel
- MANDIR    = $(mandir)/man8
- HOTPLUG_USB_DIR = /etc/hotplug/usb
-+UDEV_RULES_DIR	= /etc/udev/rules.d
- 
- XPD_FIRMWARE	= $(wildcard ../firmwares/*.hex)
- XPD_INIT_DATA	= $(XPD_FIRMWARE) init_fxo_modes
-@@ -53,6 +54,8 @@
- 	$(INSTALL) -d $(DESTDIR)$(HOTPLUG_USB_DIR)
- 	$(INSTALL_DATA) xpp_fxloader.usermap $(DESTDIR)$(HOTPLUG_USB_DIR)/
- 	$(INSTALL) xpp_fxloader $(DESTDIR)$(HOTPLUG_USB_DIR)/
-+	$(INSTALL) -d $(DESTDIR)$(UDEV_RULES_DIR)
-+	$(INSTALL_DATA) xpp.rules $(DESTDIR)$(UDEV_RULES_DIR)/
- 
- libhexfile.a: hexfile.o
- 	$(AR) cru $@ $^
-diff -urNad zaptel-1.2.12~dfsg~/xpp/utils/xpp.rules zaptel-1.2.12~dfsg/xpp/utils/xpp.rules
---- zaptel-1.2.12~dfsg~/xpp/utils/xpp.rules	1970-01-01 02:00:00.000000000 +0200
-+++ zaptel-1.2.12~dfsg/xpp/utils/xpp.rules	2007-01-08 16:05:37.000000000 +0200
-@@ -0,0 +1,8 @@
-+BUS!="usb", ACTION!="add", GOTO="xpp_usb_add_end"
-+
-+# Load firmware into the Xorcom Astribank device:
-+SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \
-+	RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}"
-+
-+LABEL="xpp_usb_add_end"
-+
-diff -urNad zaptel-1.2.12~dfsg~/xpp/utils/xpp_fxloader zaptel-1.2.12~dfsg/xpp/utils/xpp_fxloader
---- zaptel-1.2.12~dfsg~/xpp/utils/xpp_fxloader	2006-11-28 15:36:03.000000000 +0200
-+++ zaptel-1.2.12~dfsg/xpp/utils/xpp_fxloader	2007-01-08 16:05:37.000000000 +0200
-@@ -1,8 +1,8 @@
- #!/bin/sh
- 
--# xpp_fxload: load XPP firmware
-+# xpp_fxloader: load Xorcom Astribank (XPP) firmware
- #
--# This script can be run manually or from hotplug. 
-+# This script can be run manually or from hotplug/udev.
- #
- # Firmware files should be located in $FIRMWARE_DIR which defaults:
- # 	1. /usr/share/zaptel
-@@ -12,28 +12,21 @@
- # Manual Run
- # ##########
- #
--#   path/to/xpp_fxloader xppdetect
-+#   path/to/xpp_fxloader load
- #
- # Make sure the firmware files are in $FIRMWARE_DIR
- #
-+# UDEV Installation
-+# #################
- #
--# Hotplg Run
--# ##########
-+# Copy xpp.rules to /etc/udev/udev.d and xpp_fxloader to /etc/hotplug/usb/ .
- #
--# 1. Copy this file and the file xpp_fxloader.usermap to /etc/hotplug/usb/
--# 2. tail -f  /var/log/messages...
-+# Hotplug Installation
-+# ####################
- #
--# 
--# Suggested udev configuration: I used the following file as 
--# /etc/udev/rules.d/z60_zaptel.rules :
-+# Copy this file and the file xpp_fxloader.usermap to /etc/hotplug/usb/ .
- #
--# BUS!="usb", ACTION!="add", GOTO="zaptel_usb_add_end"
--# 
--# SYSFS{idVendor}=="e4e4", SYSFS{idProduct}=="11[345][01]", \
--# 	RUN+="/etc/hotplug/usb/xpp_fxloader udev $sysfs{idVendor}/$sysfs{idProduct}/$sysfs{bcdDevice}"
- # 
--# LABEL="zaptel_usb_add_end"
--#
- # Written by Tzafrir Cohen <tzafrir.cohen at xorcom.com>
- # Copyright (C) 2006, Xorcom
- #

Modified: zaptel/trunk/debian/rules
===================================================================
--- zaptel/trunk/debian/rules	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/debian/rules	2007-02-10 02:19:35 UTC (rev 3127)
@@ -123,8 +123,8 @@
 	
 	# driver source code
 	mkdir -p $(TARDIR)/debian
-	cp Makefile .version *.c *.h *.rbt $(TARDIR)/
-	for dir in build_tools include cwain qozap vzaphfc oct612x wct4xxp xpp zaphfc ztgsm; do \
+	cp Makefile Makefile.kernel26 .version *.c *.h *.rbt $(TARDIR)/
+	for dir in build_tools include cwain qozap vzaphfc oct612x wct4xxp wctc4xxp xpp zaphfc ztgsm; do \
 	  if [ -d $$dir ]; then cp -r $$dir $(TARDIR); fi; \
 	done
 	dh_install -i zaptel.h torisa.h usr/include/linux/
@@ -206,14 +206,14 @@
 	@@dh_testdir
 	@@[ -d ../tarballs/. ]||mkdir -p ../tarballs
 	@@echo Downloading $(UPFILENAME) from $(URL) ...
-	@@wget -N -nv -T10 -t3 -O ../tarballs/$(UPFILENAME) $(URL)
+	@@wget  -N -nv -T10 -t3 --verbose -O ../tarballs/$(UPFILENAME) $(URL)
 	@@echo Repacking as DFSG-free...
 	@@mkdir -p $(TARBALL_DIR)/
 	@@cd $(TARBALL_DIR) ; \
 	tar xfz ../$(UPFILENAME)
 	@@rm -rf $(TARBALL_DIR)/zaptel-$(UPVERSION)/wct4xxp/OCT*.ima
+	@@rm -rf $(TARBALL_DIR)/zaptel-$(UPVERSION)/wctc4xxp/*.bin
 	@@rm -rf $(TARBALL_DIR)/zaptel-$(UPVERSION)/xpp/firmwares/*.hex
-	@@rm -rf $(TARBALL_DIR)/zaptel-$(UPVERSION)/xpp/utils/*.hex
 	@@cd $(TARBALL_DIR) ; \
 	tar cfz ../$(FILENAME) *
 	@@echo Cleaning up...

Added: zaptel/trunk/xpp/card_bri.c
===================================================================
--- zaptel/trunk/xpp/card_bri.c	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/xpp/card_bri.c	2007-02-10 02:19:35 UTC (rev 3127)
@@ -0,0 +1,1346 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2006, Xorcom
+ *
+ * Parts derived from Cologne demo driver for the chip.
+ *
+ * All rights reserved.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include "xpd.h"
+#include "xproto.h"
+#include "xpp_zap.h"
+#include "card_bri.h"
+#include "zap_debug.h"
+#include "xpd.h"
+#include "xbus-core.h"
+
+static const char rcsid[] = "$Id: card_bri.c 3331 2007-02-07 16:05:07Z oron $";
+
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+#error CONFIG_ZAPATA_BRI_DCHANS is not defined
+#endif
+
+DEF_PARM(int, print_dbg, 0, 0600, "Print DBG statements");	/* must be before zap_debug.h */
+DEF_PARM(uint, poll_interval, 100, 0600, "Poll channel state interval in milliseconds (0 - disable)");
+
+enum xhfc_states {
+	ST_RESET		= 0,	/* G/F0	*/
+	/* TE */
+	ST_TE_SENSING		= 2,	/* F2	*/
+	ST_TE_DEACTIVATED	= 3,	/* F3	*/
+	ST_TE_SIGWAIT		= 4,	/* F4	*/
+	ST_TE_IDENT		= 5,	/* F5	*/
+	ST_TE_SYNCED		= 6,	/* F6	*/
+	ST_TE_ACTIVATED		= 7,	/* F7	*/
+	ST_TE_LOST_FRAMING	= 8,	/* F8	*/
+	/* NT */
+	ST_NT_DEACTIVATED	= 1,	/* G1	*/
+	ST_NT_ACTIVATING	= 2,	/* G2	*/
+	ST_NT_ACTIVATED		= 3,	/* G3	*/
+	ST_NT_DEACTIVTING	= 4,	/* G4	*/
+};
+
+static const char *xhfc_state_name(xpd_type_t xpd_type, enum xhfc_states state)
+{
+	const char	*p;
+
+#define	_E(x)	[ST_ ## x] = #x
+	static const char *te_names[] = {
+		_E(RESET),
+		_E(TE_SENSING),
+		_E(TE_DEACTIVATED),
+		_E(TE_SIGWAIT),
+		_E(TE_IDENT),
+		_E(TE_SYNCED),
+		_E(TE_ACTIVATED),
+		_E(TE_LOST_FRAMING),
+	};
+	static const char *nt_names[] = {
+		_E(RESET),
+		_E(NT_DEACTIVATED),
+		_E(NT_ACTIVATING),
+		_E(NT_ACTIVATED),
+		_E(NT_DEACTIVTING),
+	};
+#undef	_E
+	if(xpd_type == XPD_TYPE_BRI_TE) {
+		if ((state < ST_RESET) || (state > ST_TE_LOST_FRAMING))
+			p = "TE ???";
+		else
+			p = te_names[state];
+	} else {
+		if ((state < ST_RESET) || (state > ST_NT_DEACTIVTING))
+			p = "NT ???";
+		else
+			p = nt_names[state];
+	}
+	return p;
+}
+
+/* xhfc Layer1 physical commands */
+#define HFC_L1_ACTIVATE_TE		0x01
+#define HFC_L1_FORCE_DEACTIVATE_TE	0x02
+#define HFC_L1_ACTIVATE_NT		0x03
+#define HFC_L1_DEACTIVATE_NT		0x04
+
+#define HFC_L1_ACTIVATING	1
+#define HFC_L1_ACTIVATED	2
+#define	NT_T1_COUNT		25	/* number of 4ms interrupts for G2 timeout */
+#define	HFC_TIMER_T3		8000	/* 8s activation timer T3 */
+#define	HFC_TIMER_T4		500	/* 500ms deactivation timer T4 */
+#define	HFC_TIMER_OFF		-1	/* timer disabled */
+
+#define	A_SU_WR_STA		0x30	/* ST/Up state machine register		*/
+#define		V_SU_LD_STA	0x10
+#define 	V_SU_ACT	0x60	/* start activation/deactivation	*/
+#define 	STA_DEACTIVATE	0x40	/* start deactivation in A_SU_WR_STA */
+#define 	STA_ACTIVATE	0x60	/* start activation   in A_SU_WR_STA */
+#define 	V_SU_SET_G2_G3	0x80
+
+#define	A_SU_RD_STA		0x30
+typedef union {
+	struct {
+		byte	v_su_sta:4;
+		byte	v_su_fr_sync:1;
+		byte	v_su_t2_exp:1;
+		byte	v_su_info0:1;
+		byte	v_g2_g3:1;
+	} bits;
+	byte	reg;
+} su_rd_sta_t;
+
+#define	BRI_DCHAN_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	  \
+				)
+#define	BRI_BCHAN_SIGCAP	ZT_SIG_CLEAR
+
+
+/*---------------- BRI Protocol Commands ----------------------------------*/
+
+static int write_state_register(xpd_t *xpd, byte value);
+static bool bri_packet_is_valid(xpacket_t *pack);
+static void bri_packet_dump(const char *msg, xpacket_t *pack);
+static int proc_bri_info_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+
+#define	PROC_REGISTER_FNAME	"slics"
+#define	PROC_BRI_INFO_FNAME	"bri_info"
+
+#define	VALID_CHIPSEL(x)	((x) == 0)
+
+enum led_state {
+	BRI_LED_OFF		= 0x0,
+	BRI_LED_ON		= 0x1,
+	BRI_LED_BLINK_SLOW	= 0x2,	/* 1/2 a second blink cycle */
+	BRI_LED_BLINK_FAST	= 0x3	/* 1/4 a second blink cycle */
+};
+
+enum bri_led_names {
+	GREEN_LED	= 0,
+	RED_LED		= 1
+};
+
+#define	NUM_LEDS	2
+#define	LED_TICKS	100
+
+struct bri_leds {
+	byte	state:2;
+	byte	led_sel:1;	/* 0 - GREEN, 1 - RED */
+	byte	reserved:5;
+};
+
+#ifndef MAX_DFRAME_LEN_L1
+#define MAX_DFRAME_LEN_L1 300
+#endif
+
+#define	DCHAN_BUFSIZE	MAX_DFRAME_LEN_L1
+
+struct BRI_priv_data {
+	struct proc_dir_entry		*regfile;
+	struct proc_dir_entry		*bri_info;
+	su_rd_sta_t			state_register;
+	bool				initialized;
+	int				t3; /* timer 3 for activation */
+	int				t4; /* timer 4 for deactivation */
+	ulong				l1_flags;
+	bool				reg30_good;
+	ulong				last_reg30_reply;
+
+	/*
+	 * D-Chan: buffers + extra state info.
+	 */
+	int				dchan_r_idx;
+	byte				dchan_rbuf[DCHAN_BUFSIZE];
+	byte				dchan_tbuf[DCHAN_BUFSIZE];
+	bool				txframe_begin;
+
+	reg_cmd_t			requested_reply;
+	reg_cmd_t			last_reply;
+	uint				tick_counter;
+	uint				poll_counter;
+	uint				drop_counter;
+	enum led_state			ledstate[NUM_LEDS];
+	enum led_state			ledcontrol[NUM_LEDS];
+};
+
+xproto_table_t	PROTO_TABLE(BRI_NT);
+xproto_table_t	PROTO_TABLE(BRI_TE);
+
+
+DEF_RPACKET_DATA(BRI, SET_LED,	/* Set one of the LED's */
+	struct bri_leds		bri_leds;
+	);
+
+static /* 0x33 */ DECLARE_CMD(BRI, SET_LED, bool red_led, enum led_state to_led_state);
+static /* 0x0F */ DECLARE_CMD(BRI, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high);
+
+#define DEBUG_BUF_SIZE (100)
+static void dump_hex_buf(xpd_t *xpd, char *msg, byte *buf, int len)
+{
+	char	debug_buf[DEBUG_BUF_SIZE + 1];
+	int	i;
+	char	*p;
+	xbus_t	*xbus = xpd->xbus;
+
+	if (len >= DEBUG_BUF_SIZE) {
+		ERR("%s: dumped buffer too long. Length: %d, Maximum allowed: %d.\n",
+				__FUNCTION__, len, DEBUG_BUF_SIZE);
+		return;
+	}
+	p = debug_buf;
+	*p = '\0';
+	for(i=0; i<len; i++)
+		p += snprintf(p, DEBUG_BUF_SIZE - (p - debug_buf), "%02X ", buf[i]);
+	printk(KERN_DEBUG "%s/%s: %s[0..%d]: %s\n", xbus->busname, xpd->xpdname, msg, len-1, debug_buf);
+}
+
+static void dump_dchan_packet(xpd_t *xpd, bool transmit, byte *buf, int len)
+{
+	struct BRI_priv_data	*priv;
+	char	msgbuf[MAX_PROC_WRITE];
+	char	ftype = '?';
+	char	*direction;
+	int	frame_begin;
+
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	if(transmit) {
+		direction = "TX";
+		frame_begin = priv->txframe_begin;
+	} else {
+		direction = "RX";
+		frame_begin = 1;
+	}
+	if(frame_begin) {	/* Packet start */
+		if(!IS_SET(buf[0], 7))
+			ftype = 'I';	/* Information */
+		else if(IS_SET(buf[0], 7) && !IS_SET(buf[0], 6))
+			ftype = 'S';	/* Supervisory */
+		else if(IS_SET(buf[0], 7) && IS_SET(buf[0], 6))
+			ftype = 'U';	/* Unnumbered */
+		else
+			NOTICE("Unknown frame type 0x%X\n", buf[0]);
+
+		snprintf(msgbuf, MAX_PROC_WRITE, "D-Chan %s = (%c) ", direction, ftype);
+	} else {
+		snprintf(msgbuf, MAX_PROC_WRITE, "D-Chan %s =     ", direction);
+	}
+	dump_hex_buf(xpd, msgbuf, buf, len);
+}
+
+/*
+ * D-Chan receive
+ */
+static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
+{
+	xbus_t			*xbus;
+	struct BRI_priv_data	*priv;
+	byte			*src;
+	byte			*dst;
+	byte			*dchan_buf;
+	struct zt_chan		*dchan;
+	uint			len;
+	bool			eoframe;
+	int			idx;
+	unsigned long		flags;
+	int			ret = 0;
+
+	src = REG_XDATA(regcmd);
+	len = regcmd->bytes;
+	eoframe = regcmd->eoframe;
+	if(len <= 0)
+		return 0;
+	if(!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
+		return 0;
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	xbus = xpd->xbus;
+#ifdef XPP_DEBUGFS
+	xbus_log(xbus, xpd, 0, regcmd, sizeof(reg_cmd_t));		/* 0 = RX */
+#endif
+	spin_lock_irqsave(&xpd->lock, flags);
+	dchan = &xpd->span.chans[2];
+	if(!IS_SET(xpd->offhook, 2)) {	/* D-chan is used? */
+		static int rate_limit;
+
+		if((rate_limit++ % 1000) == 0)
+			DBG("%s/%s: D-Chan unused\n", xbus->busname, xpd->xpdname);
+		dchan->bytes2receive = 0;
+		dchan->bytes2transmit = 0;
+		goto out;
+	}
+	dchan_buf = dchan->readchunk;
+	idx = priv->dchan_r_idx;
+	if(idx + len >= DCHAN_BUFSIZE) {
+		ERR("%s/%s: D-Chan RX overflow: %d\n", xbus->busname, xpd->xpdname, idx);
+		dump_hex_buf(xpd, "    current packet", src, len);
+		dump_hex_buf(xpd, "    dchan_buf", dchan_buf, idx);
+		ret = -ENOSPC;
+		if(eoframe)
+			goto drop;
+		goto out;
+	}
+	dst = dchan_buf + idx;
+	idx += len;
+	priv->dchan_r_idx = idx;
+	memcpy(dst, src, len);
+	if(!eoframe)
+		goto out;
+	if(idx < 4) {
+		NOTICE("%s/%s: D-Chan RX short frame (idx=%d)\n", xbus->busname, xpd->xpdname, idx);
+		dump_hex_buf(xpd, "D-Chan RX:    current packet", src, len);
+		dump_hex_buf(xpd, "D-Chan RX:    chan_buf", dchan_buf, idx);
+		ret = -EPROTO;
+		goto drop;
+	}
+	if(dchan_buf[idx-1]) {
+		NOTICE("%s/%s: D-Chan RX Bad checksum: [%02X:%02X=%02X] (%d)\n",
+				xbus->busname, xpd->xpdname,
+				dchan_buf[idx-3], dchan_buf[idx-2], dchan_buf[idx-1], dchan_buf[idx-1]);
+		dump_hex_buf(xpd, "D-Chan RX:    current packet", src, len);
+		dump_hex_buf(xpd, "D-Chan RX:    chan_buf", dchan_buf, idx);
+		ret = -EPROTO;
+		goto drop;
+	}
+	if(print_dbg)
+		dump_dchan_packet(xpd, 0, dchan_buf, idx /* - 3 */);	/* Print checksum? */
+	/* 
+	 * Tell Zaptel that we received idx-1 bytes. They include the data and a 2-byte checksum.
+	 * The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
+	 * we would drop the packet in the "if(dchan_buf[idx-1])" above.
+	 */
+	dchan->bytes2receive = idx - 1;
+	dchan->eofrx = 1;
+drop:
+	priv->dchan_r_idx = 0;
+out:
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	return ret;
+}
+
+static int send_bri_multibyte(xpd_t *xpd, byte *buf, int len, bool eoftx)
+{
+	xbus_t		*xbus = xpd->xbus;
+	xframe_t	*xframe;
+	xpacket_t	*pack;
+	reg_cmd_t	*reg_cmd;
+
+	BUG_ON(len < 0);
+	/*
+	 * Zero length multibyte is legal and has special meaning for the
+	 * firmware:
+	 *   eoftx==1: Start sending us D-channel packets.
+	 *   eoftx==0: Stop sending us D-channel packets.
+	 */
+	if(len > MULTIBYTE_MAX_LEN) {
+		ERR("%s: len=%d is too long. dropping.\n", __FUNCTION__, len);
+		return -EINVAL;
+	}
+	XFRAME_NEW(xframe, pack, xbus, BRI, REGISTER_REQUEST, xpd->id);
+	reg_cmd = &RPACKET_FIELD(pack, BRI, REGISTER_REQUEST, reg_cmd);
+	reg_cmd->bytes = len;
+	reg_cmd->eoframe = eoftx;
+	reg_cmd->multibyte = 1;
+	if(len > 0) {
+		memcpy(REG_XDATA(reg_cmd), (byte *)buf, len);
+	} else {
+		DBG("Magic Packet (eoftx=%d)\n", eoftx);
+	}
+#ifdef XPP_DEBUGFS
+	xbus_log(xbus, xpd, 1, reg_cmd, sizeof(reg_cmd_t));	/* 1 = TX */
+#endif
+	return xframe_send(xbus, xframe);
+}
+
+/*
+ * D-Chan transmit
+ */
+static int tx_dchan(xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+	struct zt_chan		*dchan;
+	int			len;
+	int			eoframe;
+
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	if(xpd->type == XPD_TYPE_BRI_TE) {
+		static int	rate_limit;
+
+		if (priv->t3 > HFC_TIMER_OFF) {
+			/* timer expired ? */
+			if (--priv->t3 == 0) {
+				if ((rate_limit % 1003) >= 5)
+					DBG("%s/%s: T3 expired\n", xpd->xbus->busname, xpd->xpdname);
+				priv->t3 = HFC_TIMER_OFF;
+				clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+				CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0);	/* Deactivate TE */
+			}
+		}
+		if (priv->t4 > HFC_TIMER_OFF) {
+			/* timer expired ? */
+			if (--priv->t4 == 0) {
+				if ((rate_limit % 1003) >= 5)
+					DBG("%s/%s: T4 expired\n", xpd->xbus->busname, xpd->xpdname);
+				priv->t4 = HFC_TIMER_OFF;
+			}
+		}
+		rate_limit++;
+	}
+	if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & ZT_FLAG_RUNNING))
+		return 0;
+	dchan = &xpd->chans[2];
+	len = dchan->bytes2transmit;	/* dchan's hdlc package len */
+	eoframe = dchan->eoftx;		/* dchan's end of frame */
+	dchan->bytes2transmit = 0;
+	dchan->eoftx = 0;
+	dchan->bytes2receive = 0;
+	dchan->eofrx = 0;
+	if(len <= 0)
+		return 0; /* Nothing to transmit on D channel */
+	if(len > MULTIBYTE_MAX_LEN) {
+		ERR("%s: len=%d. need to split. Unimplemented.\n", __FUNCTION__, len);
+		return -EINVAL;
+	}
+	if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
+		CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1);	/* Kick transmitter */
+		return 0;
+	}
+	if(print_dbg)
+		dump_dchan_packet(xpd, 1, priv->dchan_tbuf, len);
+	if(eoframe)
+		priv->txframe_begin = 1;
+	else
+		priv->txframe_begin = 0;
+	return send_bri_multibyte(xpd, priv->dchan_tbuf, len, eoframe);
+}
+
+/*---------------- BRI: Methods -------------------------------------------*/
+
+static xpd_t *BRI_card_new(xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, byte revision)
+{
+	xpd_t		*xpd = NULL;
+	int		channels = min(3, CHANNELS_PERXPD);
+
+	DBG("\n");
+
+	xpd = xpd_alloc(sizeof(struct BRI_priv_data), xbus, xpd_num, proto_table, channels, revision);
+	if(!xpd)
+		return NULL;
+	xpd->direction = (proto_table == &PROTO_TABLE(BRI_NT)) ? TO_PHONE : TO_PSTN;
+	xpd->revision = revision;
+	return xpd;
+}
+
+static void clean_proc(xbus_t *xbus, xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	DBG("%s/%s\n", xbus->busname, xpd->xpdname);
+#ifdef	CONFIG_PROC_FS
+	if(priv->regfile) {
+		DBG("Removing registers file for %s/%s\n", xbus->busname, xpd->xpdname);
+		priv->regfile->data = NULL;
+		remove_proc_entry(PROC_REGISTER_FNAME, xpd->proc_xpd_dir);
+	}
+	if(priv->bri_info) {
+		DBG("Removing xpd BRI_INFO file %s/%s\n", xbus->busname, xpd->xpdname);
+		remove_proc_entry(PROC_BRI_INFO_FNAME, xpd->proc_xpd_dir);
+	}
+#endif
+}
+
+static int BRI_card_init(xbus_t *xbus, xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+	int			ret = 0;
+
+	DBG("\n");
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+#ifdef	CONFIG_PROC_FS
+	DBG("Creating BRI_INFO file for %s/%s\n", xbus->busname, xpd->xpdname);
+	priv->bri_info = create_proc_read_entry(PROC_BRI_INFO_FNAME, 0444, xpd->proc_xpd_dir, proc_bri_info_read, xpd);
+	if(!priv->bri_info) {
+		ERR("Failed to create proc '%s' for %s/%s\n", PROC_BRI_INFO_FNAME, xbus->busname, xpd->xpdname);
+		ret = -ENOENT;
+		goto err;
+	}
+	priv->bri_info->owner = THIS_MODULE;
+	DBG("Creating registers file for %s/%s\n", xbus->busname, xpd->xpdname);
+	priv->regfile = create_proc_entry(PROC_REGISTER_FNAME, 0644, xpd->proc_xpd_dir);
+	if(!priv->regfile) {
+		ERR("Failed to create proc file for registers of %s/%s\n", xbus->busname, xpd->xpdname);
+		goto err;
+	}
+	priv->regfile->owner = THIS_MODULE;
+	priv->regfile->write_proc = proc_xpd_register_write;
+	priv->regfile->read_proc = proc_xpd_register_read;
+	priv->regfile->data = xpd;
+#endif
+	ret = run_initialize_registers(xpd);
+	if(ret < 0)
+		goto err;
+	DBG("done: %s/%s\n", xbus->busname, xpd->xpdname);
+	priv->initialized = 1;
+	CALL_PROTO(BRI, SET_LED, xbus, xpd, GREEN_LED, BRI_LED_ON);
+	CALL_PROTO(BRI, SET_LED, xbus, xpd, RED_LED, BRI_LED_ON);
+	msleep(10);
+	return 0;
+err:
+	clean_proc(xbus, xpd);
+	ERR("%s/%s: Failed initializing registers (%d)\n", xbus->busname, xpd->xpdname, ret);
+	return ret;
+}
+
+static int BRI_card_remove(xbus_t *xbus, xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	DBG("%s/%s\n", xbus->busname, xpd->xpdname);
+	clean_proc(xbus, xpd);
+	return 0;
+}
+
+static int BRI_card_zaptel_preregistration(xpd_t *xpd, bool on)
+{
+	xbus_t			*xbus;
+	struct BRI_priv_data	*priv;
+	int			i;
+	
+	BUG_ON(!xpd);
+	xbus = xpd->xbus;
+	priv = xpd->priv;
+	BUG_ON(!xbus);
+	DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off");
+	if(!on) {
+		/* Nothing to do yet */
+		return 0;
+	}
+	snprintf(xpd->span.desc, MAX_SPANDESC, "Xorcom XPD #%d/%d: %s",
+			xbus->num, xpd->id,
+			xpd->xproto->name
+			);
+	xpd->span.linecompat = ZT_CONFIG_AMI | ZT_CONFIG_CCS;
+	xpd->span.deflaw = ZT_LAW_ALAW;
+	BIT_SET(xpd->digital_signalling, 2);	/* D-Channel */
+	for_each_line(xpd, i) {
+		struct zt_chan	*cur_chan = &xpd->chans[i];
+
+		DBG("setting BRI channel %d\n", i);
+		snprintf(cur_chan->name, MAX_CHANNAME, "XPP_%s/%d/%d/%d",
+				xpd->xproto->name, xbus->num, xpd->id, i);
+		cur_chan->chanpos = i + 1;
+		cur_chan->pvt = xpd;
+		if(i == 2) {	/* D-CHAN */
+			cur_chan->sigcap = BRI_DCHAN_SIGCAP;
+			cur_chan->flags |= ZT_FLAG_BRIDCHAN;
+			cur_chan->flags &= ~ZT_FLAG_HDLC;
+
+			/* Setup big buffers for D-Channel rx/tx */
+			cur_chan->readchunk = priv->dchan_rbuf;
+			cur_chan->writechunk = priv->dchan_tbuf;
+			priv->dchan_r_idx = 0;
+			priv->txframe_begin = 1;
+
+			cur_chan->maxbytes2transmit = MULTIBYTE_MAX_LEN;
+			cur_chan->bytes2transmit = 0;
+			cur_chan->bytes2receive = 0;
+		} else
+			cur_chan->sigcap = BRI_BCHAN_SIGCAP;
+	}
+	xpd->offhook = BIT(0) | BIT(1);	/* 2*bchan */
+	return 0;
+}
+
+static int BRI_card_zaptel_postregistration(xpd_t *xpd, bool on)
+{
+	xbus_t			*xbus;
+	struct BRI_priv_data	*priv;
+	
+	BUG_ON(!xpd);
+	xbus = xpd->xbus;
+	priv = xpd->priv;
+	BUG_ON(!xbus);
+	DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"on":"off");
+	msleep(10);
+	CALL_PROTO(BRI, SET_LED, xbus, xpd, GREEN_LED, BRI_LED_OFF);
+	CALL_PROTO(BRI, SET_LED, xbus, xpd, RED_LED, BRI_LED_OFF);
+	return(0);
+}
+
+int BRI_card_hooksig(xbus_t *xbus, xpd_t *xpd, int pos, zt_txsig_t txsig)
+{
+	DBG("%s/%s/%d: %s\n", xbus->busname, xpd->xpdname, pos, txsig2str(txsig));
+	return 0;
+}
+
+/* Poll the register ST/Up-State-machine Register, to see if the cable
+ * if a cable is connected to the port.
+ */
+static int BRI_card_tick(xbus_t *xbus, xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	if(!priv->initialized)
+		return 0;
+	if(poll_interval != 0 && (priv->tick_counter % poll_interval) == 0) {
+		// DBG("%d\n", priv->tick_counter);
+		priv->poll_counter++;
+		CALL_PROTO(BRI, REGISTER_REQUEST, xbus, xpd, 0, 0, 0, A_SU_RD_STA, 0, 0, 0);
+	}
+	if((priv->tick_counter % LED_TICKS) == 0) {
+		int	i;
+
+		if(priv->reg30_good && time_before(priv->last_reg30_reply + HZ/2, jiffies)) {
+			/* No reply for 1/2 a second */
+			ERR("%s/%s: Lost state tracking\n", xbus->busname, xpd->xpdname);
+			priv->reg30_good = 0;
+		}
+		if(!priv->reg30_good) {
+			priv->ledcontrol[RED_LED] = BRI_LED_OFF;
+			priv->ledcontrol[GREEN_LED] = BRI_LED_OFF;
+		}
+		for(i = 0; i < NUM_LEDS; i++) {
+			if(xpd->blink_mode) {
+				CALL_PROTO(BRI, SET_LED, xbus, xpd, i, BRI_LED_BLINK_FAST);
+			} else if(priv->ledstate[i] != priv->ledcontrol[i]) {
+				CALL_PROTO(BRI, SET_LED, xbus, xpd, i,
+						priv->ledcontrol[i]);
+			}
+		}
+	}
+	tx_dchan(xpd);
+	priv->tick_counter++;
+	return 0;
+}
+
+static int BRI_span_startup(xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	DBG("%s/%s: STARTUP\n", xpd->xbus->busname, xpd->xpdname);
+	write_state_register(xpd, 0);	/* Enable L1 state machine */
+	CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 1);
+	if(SPAN_REGISTERED(xpd))
+		xpd->span.flags |= ZT_FLAG_RUNNING;
+	return 0;
+}
+
+static int BRI_span_shutdown(xpd_t *xpd)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	DBG("%s/%s: SHUTDOWN\n", xpd->xbus->busname, xpd->xpdname);
+	if(xpd->type == XPD_TYPE_BRI_NT)
+		CALL_XMETHOD(XPD_STATE, xpd->xbus, xpd, 0);
+	return 0;
+}
+
+/*---------------- BRI: HOST COMMANDS -------------------------------------*/
+
+/* 0x0F */ HOSTCMD(BRI, REGISTER_REQUEST, byte chipsel, bool writing, bool do_subreg, byte regnum, byte subreg, byte data_low, byte data_high)
+{
+	int		ret = 0;
+	xframe_t	*xframe;
+	xpacket_t	*pack;
+	reg_cmd_t	*reg_cmd;
+
+	if(!xbus) {
+		DBG("NO XBUS\n");
+		return -EINVAL;
+	}
+	XFRAME_NEW(xframe, pack, xbus, BRI, REGISTER_REQUEST, xpd->id);
+#if 0
+	DBG("%s/%s/%d: %c%c R%02X S%02X %02X %02X\n",
+			xbus->busname, xpd->xpdname, chipsel,
+			(writing)?'W':'R',
+			(do_subreg)?'S':'D',
+			regnum, subreg, data_low, data_high);
+#endif
+	reg_cmd = &RPACKET_FIELD(pack, BRI, REGISTER_REQUEST, reg_cmd);
+	reg_cmd->bytes = sizeof(*reg_cmd) - 1;	// do not count the 'bytes' field
+	REG_FIELD(reg_cmd, chipsel) = chipsel;
+	REG_FIELD(reg_cmd, read_request) = (writing) ? 0 : 1;
+	REG_FIELD(reg_cmd, do_subreg) = do_subreg;
+	REG_FIELD(reg_cmd, regnum) = regnum;
+	REG_FIELD(reg_cmd, subreg) = subreg;
+	REG_FIELD(reg_cmd, data_low) = data_low;
+	REG_FIELD(reg_cmd, data_high) = data_high;
+	ret = xframe_send(xbus, xframe);
+	return ret;
+}
+
+/* 0x0F */ HOSTCMD(BRI, XPD_STATE, bool on)
+{
+	struct BRI_priv_data	*priv;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	DBG("%s/%s: %s\n", xbus->busname, xpd->xpdname, (on)?"ON":"OFF");
+	switch(xpd->type) {
+		case XPD_TYPE_BRI_TE:
+			if(on) {
+				DBG("%s/%s: HFC_L1_ACTIVATE_TE\n", xbus->busname, xpd->xpdname);
+				set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+				write_state_register(xpd, STA_ACTIVATE);
+				priv->t3 = HFC_TIMER_T3;
+			} else {
+				DBG("%s/%s: HFC_L1_FORCE_DEACTIVATE_TE\n", xbus->busname, xpd->xpdname);
+				write_state_register(xpd, STA_DEACTIVATE);
+			}
+			break;
+		case XPD_TYPE_BRI_NT:
+			if(on) {
+				DBG("%s/%s: HFC_L1_ACTIVATE_NT\n", xbus->busname, xpd->xpdname);
+				set_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+				write_state_register(xpd, STA_ACTIVATE | V_SU_SET_G2_G3);
+			} else {
+				DBG("%s/%s: HFC_L1_DEACTIVATE_NT\n", xbus->busname, xpd->xpdname);
+				write_state_register(xpd, STA_DEACTIVATE);
+			}
+			break;
+		default:
+			ERR("%s: %s/%s: Bad xpd type %d\n", __FUNCTION__,
+					xbus->busname, xpd->xpdname, xpd->type);
+			return -EINVAL;
+	}
+	return 0;
+}
+
+/* 0x0F */ HOSTCMD(BRI, RING, lineno_t chan, bool on)
+{
+	ERR("%s: Unsupported\n", __FUNCTION__);
+	return -ENOSYS;
+}
+
+/* 0x0F */ HOSTCMD(BRI, RELAY_OUT, byte which, bool on)
+{
+	ERR("%s: Unsupported\n", __FUNCTION__);
+	return -ENOSYS;
+}
+
+/* 0x33 */ HOSTCMD(BRI, SET_LED, bool red_led, enum led_state to_led_state)
+{
+	int			ret = 0;
+	xframe_t	*xframe;
+	xpacket_t		*pack;
+	struct bri_leds		*bri_leds;
+	struct BRI_priv_data	*priv;
+	int			which_led = (red_led) ? RED_LED : GREEN_LED;
+
+	BUG_ON(!xbus);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	XFRAME_NEW(xframe, pack, xbus, BRI, SET_LED, xpd->id);
+#if 1
+	DBG("%s/%s: %s %d\n", xbus->busname, xpd->xpdname,
+			(red_led)?"RED":"GREEN", to_led_state);
+#endif
+	bri_leds = &RPACKET_FIELD(pack, BRI, SET_LED, bri_leds);
+	bri_leds->state = to_led_state;
+	bri_leds->led_sel = which_led;
+	pack->datalen = RPACKET_SIZE(BRI, SET_LED);
+	ret = xframe_send(xbus, xframe);
+	priv->ledstate[which_led] = to_led_state;
+	return ret;
+}
+
+static int write_state_register(xpd_t *xpd, byte value)
+{
+	int	ret;
+
+	DBG("%s/%s: value = 0x%02X\n", xpd->xbus->busname, xpd->xpdname, value);
+	ret = CALL_PROTO(BRI, REGISTER_REQUEST, xpd->xbus, xpd,
+			0,		/* chipsel	*/
+			1,		/* writing	*/
+			0,		/* do_subreg	*/
+			A_SU_WR_STA,	/* regnum	*/
+			0,		/* subreg	*/
+			value,		/* data_low	*/
+			0		/* data_high	*/
+			);
+	return ret;
+}
+
+
+/*---------------- BRI: Astribank Reply Handlers --------------------------*/
+static void su_new_state(xpd_t *xpd, byte reg_x30)
+{
+	xbus_t			*xbus;
+	struct BRI_priv_data	*priv;
+	su_rd_sta_t		new_state;
+	int			which_led = (xpd->type == XPD_TYPE_BRI_TE) ? GREEN_LED : RED_LED;
+
+	BUG_ON(!xpd);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	xbus = xpd->xbus;
+	new_state.reg = reg_x30;
+	priv->last_reg30_reply = jiffies;
+	priv->reg30_good = 1;
+	if((xpd->type == XPD_TYPE_BRI_TE && new_state.bits.v_su_sta == ST_TE_ACTIVATED) ||
+		(xpd->type == XPD_TYPE_BRI_NT && new_state.bits.v_su_sta == ST_NT_ACTIVATED)) {
+		priv->ledcontrol[which_led] = (new_state.bits.v_su_fr_sync) ? BRI_LED_BLINK_SLOW : BRI_LED_BLINK_FAST;
+		update_xpd_status(xpd, ZT_ALARM_NONE);
+	} else {
+		priv->ledcontrol[which_led] = BRI_LED_OFF;
+		update_xpd_status(xpd, ZT_ALARM_RED);
+	}
+	if (priv->state_register.bits.v_su_sta == new_state.bits.v_su_sta)
+		return;	/* same same */
+	DBG("%02X ---> %02X\n", priv->state_register.reg, reg_x30);
+	DBG("%s/%s: %s%i\n", xpd->xbus->busname, xpd->xpdname,
+				(xpd->type == XPD_TYPE_BRI_NT)?"G":"F",
+				new_state.bits.v_su_sta);
+
+	if(xpd->type == XPD_TYPE_BRI_TE) {
+		/* disable T3 ? */
+		if ((new_state.bits.v_su_sta <= ST_TE_DEACTIVATED) || (new_state.bits.v_su_sta >= ST_TE_ACTIVATED)) {
+			DBG("%s/%s: Disable T3 ?\n", xbus->busname, xpd->xpdname);
+			priv->t3 = HFC_TIMER_OFF;
+		}
+		switch (new_state.bits.v_su_sta) {
+			case ST_TE_DEACTIVATED:		/* F3 */
+				DBG("%s/%s: State ST_TE_DEACTIVATED (F3)\n", xbus->busname, xpd->xpdname);
+				if (test_and_clear_bit(HFC_L1_ACTIVATED, &priv->l1_flags))
+					priv->t4 = HFC_TIMER_T4;
+				break;
+			case ST_TE_SIGWAIT:		/* F4	*/
+				DBG("%s/%s: State ST_TE_SIGWAIT (F4)\n", xbus->busname, xpd->xpdname);
+				break;
+			case ST_TE_IDENT:		/* F5	*/
+				DBG("%s/%s: State ST_TE_IDENT (F5)\n", xbus->busname, xpd->xpdname);
+				break;
+			case ST_TE_SYNCED:		/* F6	*/
+				DBG("%s/%s: State ST_TE_SYNCED (F6)\n", xbus->busname, xpd->xpdname);
+				break;
+			case ST_TE_ACTIVATED:		/* F7 */
+				DBG("%s/%s: State ST_TE_ACTIVATED (F7)\n", xbus->busname, xpd->xpdname);
+				if (priv->t4 > HFC_TIMER_OFF)
+					priv->t4 = HFC_TIMER_OFF;
+				clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+				set_bit(HFC_L1_ACTIVATED, &priv->l1_flags);
+				update_xpd_status(xpd, ZT_ALARM_NONE);
+				break;
+
+			case ST_TE_LOST_FRAMING:	/* F8 */
+				DBG("%s/%s: State ST_TE_LOST_FRAMING (F8)\n", xbus->busname, xpd->xpdname);
+				priv->t4 = HFC_TIMER_OFF;
+				break;
+			default:
+				NOTICE("%s/%s: Bad TE state: %d\n", xbus->busname, xpd->xpdname, new_state.bits.v_su_sta);
+				break;
+		}
+
+	} else if(xpd->type == XPD_TYPE_BRI_NT) {
+		switch (new_state.bits.v_su_sta) {
+			case ST_NT_DEACTIVATED:		/* G1 */
+				DBG("%s/%s: State ST_NT_DEACTIVATED (G1)\n", xbus->busname, xpd->xpdname);
+				clear_bit(HFC_L1_ACTIVATED, &priv->l1_flags);
+				break;
+			case ST_NT_ACTIVATING:		/* G2 */
+				DBG("%s/%s: State ST_NT_ACTIVATING (G2)\n", xbus->busname, xpd->xpdname);
+				write_state_register(xpd, V_SU_SET_G2_G3);	/* Enable transition to G3 */
+				break;
+			case ST_NT_ACTIVATED:		/* G3 */
+				DBG("%s/%s: State ST_NT_ACTIVATED (G3)\n", xbus->busname, xpd->xpdname);
+				clear_bit(HFC_L1_ACTIVATING, &priv->l1_flags);
+				set_bit(HFC_L1_ACTIVATED, &priv->l1_flags);
+				break;
+			case ST_NT_DEACTIVTING:		/* G4 */
+				DBG("%s/%s: State ST_NT_DEACTIVTING (G4)\n", xbus->busname, xpd->xpdname);
+				break;
+			default:
+				NOTICE("%s/%s: Bad NT state: %d\n", xbus->busname, xpd->xpdname, new_state.bits.v_su_sta);
+				break;
+		}
+	} else
+		ERR("%s: %s/%s: Unknown xpd type %d\n", __FUNCTION__,
+				xpd->xbus->busname, xpd->xpdname, xpd->type);
+	priv->state_register.reg = new_state.reg;
+}
+
+HANDLER_DEF(BRI, REGISTER_REPLY)
+{
+	reg_cmd_t		*info = &RPACKET_FIELD(pack, BRI, REGISTER_REPLY, regcmd);
+	unsigned long		flags;
+	struct BRI_priv_data	*priv;
+	int			ret;
+
+	if(!xpd) {
+		NOTICE("%s: received %s for non-existing xpd: %d\n",
+				__FUNCTION__, cmd->name, XPD_NUM(pack->addr));
+		return -EPROTO;
+	}
+	spin_lock_irqsave(&xpd->lock, flags);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+#if 0
+	if(REG_FIELD(info, do_subreg)) {
+		DBG("REGISTER_REPLY: %s/%s: RS %02X %02X %02X\n",
+				xbus->busname, xpd->xpdname, REG_FIELD(info, regnum), REG_FIELD(info, subreg), REG_FIELD(info, data_low));
+	} else {
+		if (REG_FIELD(info, regnum) != A_SU_RD_STA)
+			DBG("REGISTER_REPLY: %s/%s: RD %02X %02X\n",
+					xbus->busname, xpd->xpdname, REG_FIELD(info, regnum), REG_FIELD(info, data_low));
+	}
+#endif
+	if(info->multibyte) {
+#if 0
+		DBG("%s/%s: Got Multibyte: %d bytes, eoframe: %d\n",
+				xbus->busname, xpd->xpdname,
+				info->bytes, info->eoframe);
+#endif
+		ret = rx_dchan(xpd, info);
+		if (ret < 0) {
+			priv->drop_counter++;
+			if(atomic_read(&xpd->open_counter) > 0)
+				NOTICE("%s/%s: Multibyte Drop: errno=%d\n", xbus->busname, xpd->xpdname, ret);
+		} 
+		goto end;
+	}
+	if(REG_FIELD(info, regnum) == A_SU_RD_STA) {
+		su_new_state(xpd, REG_FIELD(info, data_low));
+	}
+
+	/* Update /proc info only if reply relate to the last slic read request */
+	if(
+			REG_FIELD(&priv->requested_reply, regnum) == REG_FIELD(info, regnum) &&
+			REG_FIELD(&priv->requested_reply, do_subreg) == REG_FIELD(info, do_subreg) &&
+			REG_FIELD(&priv->requested_reply, subreg) == REG_FIELD(info, subreg)) {
+		priv->last_reply = *info;
+	}
+	
+end:
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	return 0;
+}
+
+xproto_table_t PROTO_TABLE(BRI_NT) = {
+	.owner = THIS_MODULE,
+	.entries = {
+		/*	Table	Card	Opcode		*/
+		XENTRY(	BRI_NT,	BRI,	REGISTER_REPLY		),
+	},
+	.name = "BRI_NT",
+	.type = XPD_TYPE_BRI_NT,
+	.xops = {
+		.card_new	= BRI_card_new,
+		.card_init	= BRI_card_init,
+		.card_remove	= BRI_card_remove,
+		.card_zaptel_preregistration	= BRI_card_zaptel_preregistration,
+		.card_zaptel_postregistration	= BRI_card_zaptel_postregistration,
+		.card_hooksig	= BRI_card_hooksig,
+		.card_tick	= BRI_card_tick,
+		.span_startup	= BRI_span_startup,
+		.span_shutdown	= BRI_span_shutdown,
+
+		.RING		= XPROTO_CALLER(BRI, RING),
+		.RELAY_OUT	= XPROTO_CALLER(BRI, RELAY_OUT),
+		.XPD_STATE	= XPROTO_CALLER(BRI, XPD_STATE),
+
+		.SYNC_SOURCE	= XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
+	},
+	.packet_is_valid = bri_packet_is_valid,
+	.packet_dump = bri_packet_dump,
+};
+
+xproto_table_t PROTO_TABLE(BRI_TE) = {
+	.owner = THIS_MODULE,
+	.entries = {
+		/*	Table	Card	Opcode		*/
+		XENTRY(	BRI_TE,	BRI,	REGISTER_REPLY		),
+	},
+	.name = "BRI_TE",
+	.type = XPD_TYPE_BRI_TE,
+	.xops = {
+		.card_new	= BRI_card_new,
+		.card_init	= BRI_card_init,
+		.card_remove	= BRI_card_remove,
+		.card_zaptel_preregistration	= BRI_card_zaptel_preregistration,
+		.card_zaptel_postregistration	= BRI_card_zaptel_postregistration,
+		.card_hooksig	= BRI_card_hooksig,
+		.card_tick	= BRI_card_tick,
+		.span_startup	= BRI_span_startup,
+		.span_shutdown	= BRI_span_shutdown,
+
+		.RING		= XPROTO_CALLER(BRI, RING),
+		.RELAY_OUT	= XPROTO_CALLER(BRI, RELAY_OUT),
+		.XPD_STATE	= XPROTO_CALLER(BRI, XPD_STATE),
+
+		.SYNC_SOURCE	= XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
+	},
+	.packet_is_valid = bri_packet_is_valid,
+	.packet_dump = bri_packet_dump,
+};
+
+static bool bri_packet_is_valid(xpacket_t *pack)
+{
+	const xproto_entry_t	*xe_nt = NULL;
+	const xproto_entry_t	*xe_te = NULL;
+	// DBG("\n");
+	xe_nt = xproto_card_entry(&PROTO_TABLE(BRI_NT), pack->opcode);
+	xe_te = xproto_card_entry(&PROTO_TABLE(BRI_TE), pack->opcode);
+	return xe_nt != NULL || xe_te != NULL;
+}
+
+static void bri_packet_dump(const char *msg, xpacket_t *pack)
+{
+	DBG("%s\n", msg);
+}
+/*------------------------- REGISTER Handling --------------------------*/
+
+static int proc_bri_info_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int			len = 0;
+	unsigned long		flags;
+	xpd_t			*xpd = data;
+	struct BRI_priv_data	*priv;
+	int			led;
+
+	DBG("\n");
+	if(!xpd)
+		return -ENODEV;
+	spin_lock_irqsave(&xpd->lock, flags);
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	len += sprintf(page + len, "%05d Layer 1 State: ", priv->poll_counter);
+	if(priv->reg30_good) {
+		len += sprintf(page + len, "%c%d %-15s -- fr_sync=%d t2_exp=%d info0=%d g2_g3=%d\n",
+					(xpd->type == XPD_TYPE_BRI_NT)?'G':'F',
+					priv->state_register.bits.v_su_sta,
+					xhfc_state_name(xpd->type, priv->state_register.bits.v_su_sta),
+					priv->state_register.bits.v_su_fr_sync,
+					priv->state_register.bits.v_su_t2_exp,
+					priv->state_register.bits.v_su_info0,
+					priv->state_register.bits.v_g2_g3);
+	} else
+		len += sprintf(page + len, "Unkown\n");
+	len += sprintf(page + len, "Tick Counter: %d\n", priv->tick_counter);
+	len += sprintf(page + len, "Last Poll Reply at: %ld\n", priv->last_reg30_reply);
+	len += sprintf(page + len, "reg30_good=%d\n", priv->reg30_good);
+	len += sprintf(page + len, "Drop Counter: %d\n", priv->drop_counter);
+	for(led = 0; led < NUM_LEDS; led++) {
+		len += sprintf(page + len, "LED #%d\n", led);
+		len += sprintf(page + len, "\tledstate  : %d\n", priv->ledstate[led]);
+		len += sprintf(page + len, "\tledcontrol: %d\n", priv->ledcontrol[led]);
+	}
+	len += sprintf(page + len, "\nDCHAN:\n");
+	len += sprintf(page + len, "\n");
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	if (len <= off+count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+
+/*
+ *
+ * Direct/Indirect
+ *     |
+ *     | Reg#
+ *     | |
+ *     | |  Data (only in Write)
+ *     | |    |
+ *     | |  +-+-+
+ *     v v  v   v
+ * FF WD 06 01 05
+ * ^  ^
+ * |  |
+ * |  Write/Read
+ * |
+ * Chan#
+ *
+ */
+static int handle_register_command(xpd_t *xpd, char *cmdline)
+{
+	unsigned		chipsel;
+	unsigned		data = 0;
+	unsigned		xdata1 = 0;
+	unsigned		xdata2 = 0;
+	char			op;		/* [W]rite, [R]ead */
+	char			reg_type;	/* [D]irect, [S]ubregister */
+	int			reg_num;
+	int			subreg;
+	int			elements;
+	bool			writing;
+	char			*p;
+	reg_cmd_t		regcmd;
+	xbus_t			*xbus;
+	int			ret;
+	struct BRI_priv_data	*priv;
+	byte			buf[MAX_PROC_WRITE];
+
+	if((p = strchr(cmdline, '#')) != NULL)	/* Truncate comments */
+		*p = '\0';
+	if((p = strchr(cmdline, ';')) != NULL)	/* Truncate comments */
+		*p = '\0';
+	for(p = cmdline; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */
+		;
+	if(*p == '\0')
+		return 0;
+
+	memset(buf, 0, MAX_PROC_WRITE);
+	elements = sscanf(cmdline, "%d %c%c %x %x %x %x %x",
+			&chipsel,
+			&op, &reg_type, &reg_num,
+			&subreg,
+			&data, &xdata1, &xdata2);
+	// DBG("'%s': %d %c%c %02X %02X %02X\n", cmdline, chipsel, op, reg_type, reg_num, subreg, data);
+	if(elements < 3) {	// At least: chipsel, op, reg_type, reg_num
+		ERR("Not enough arguments: (%d args) '%s'\n", elements, cmdline);
+		return -EINVAL;
+	}
+	if(!VALID_CHIPSEL(chipsel)) {
+		ERR("Bad chip select number: %d\n", chipsel);
+		return -EINVAL;
+	}
+	REG_FIELD(&regcmd, chipsel) = chipsel;
+	switch(op) {
+		case 'W':
+			writing = 1;
+			break;
+		case 'R':
+			writing = 0;
+			break;
+		default:
+			ERR("Unkown operation type '%c'\n", op);
+			return -EINVAL;
+	}
+	if(
+			(op == 'W' && reg_type == 'D' && elements != 5) ||
+			(op == 'W' && reg_type == 'S' && elements != 6) ||
+			(op == 'R' && reg_type == 'D' && elements != 4) ||
+			(op == 'R' && reg_type == 'S' && elements != 4)
+	  ) {
+		ERR("Bad number of elements: '%s' (%d elements): %d %c%c %02X %02X %02X\n",
+				cmdline, elements,
+				chipsel, op, reg_type, reg_num, subreg, data);
+		return -EINVAL;
+	}
+	switch(reg_type) {
+		case 'S':
+			REG_FIELD(&regcmd, do_subreg) = 1;
+			REG_FIELD(&regcmd, regnum) = reg_num;
+			REG_FIELD(&regcmd, subreg) = subreg;
+			REG_FIELD(&regcmd, data_low) = data;
+			break;
+		case 'D':
+			REG_FIELD(&regcmd, do_subreg) = 0;
+			REG_FIELD(&regcmd, regnum) = reg_num;
+			REG_FIELD(&regcmd, subreg) = 0;
+			REG_FIELD(&regcmd, data_low) = subreg;
+			break;
+		case 'M':	/* Multi without eoftx */
+		case 'm':	/* Multi with eoftx */
+			if(!writing) {
+				ERR("Read multibyte is not implemented\n");
+				return -EINVAL;
+			}
+			elements -= 3;
+			REG_XDATA(&regcmd)[0] = reg_num;
+			REG_XDATA(&regcmd)[1] = subreg;
+			REG_XDATA(&regcmd)[2] = data;
+			REG_XDATA(&regcmd)[3] = xdata1;
+			REG_XDATA(&regcmd)[4] = xdata2;
+			return send_bri_multibyte(xpd, REG_XDATA(&regcmd), elements, (reg_type == 'm'));
+		default:
+			ERR("Unkown register type '%c'\n", reg_type);
+			return -EINVAL;
+	}
+	regcmd.bytes = sizeof(regcmd) - 1;
+	REG_FIELD(&regcmd, read_request) = writing;
+	REG_FIELD(&regcmd, data_high) = 0;
+	BUG_ON(!xpd);
+	xbus = xpd->xbus;
+	if(!down_read_trylock(&xbus->in_use)) {
+		DBG("Dropped packet. %s is in_use\n", xbus->busname);
+		return -EBUSY;
+	}
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	priv->requested_reply = regcmd;
+	if(print_dbg)
+		dump_reg_cmd("BRI", &regcmd);
+	ret = CALL_PROTO(BRI, REGISTER_REQUEST, xpd->xbus, xpd,
+			REG_FIELD(&regcmd, chipsel),
+			writing,
+			REG_FIELD(&regcmd, do_subreg),
+			REG_FIELD(&regcmd, regnum),
+			REG_FIELD(&regcmd, subreg),
+			REG_FIELD(&regcmd, data_low),
+			REG_FIELD(&regcmd, data_high));
+	up_read(&xbus->in_use);
+	return ret;
+}
+
+static int proc_xpd_register_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+	xpd_t		*xpd = data;
+	char		buf[MAX_PROC_WRITE];
+	char		*p;
+	int		i;
+	int		ret;
+
+	if(!xpd)
+		return -ENODEV;
+	for(i = 0; i < count; /* noop */) {
+		for(p = buf; p < buf + MAX_PROC_WRITE; p++) {	/* read a line */
+			if(i >= count)
+				break;
+			if(get_user(*p, buffer + i))
+				return -EFAULT;
+			i++;
+			if(*p == '\n' || *p == '\r')	/* whatever */
+				break;
+		}
+		if(p >= buf + MAX_PROC_WRITE)
+			return -E2BIG;
+		*p = '\0';
+		ret = handle_register_command(xpd, buf);
+		if(ret < 0)
+			return ret;
+		msleep(1);
+	}
+	return count;
+}
+
+
+static int proc_xpd_register_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	int			len = 0;
+	unsigned long		flags;
+	xpd_t			*xpd = data;
+	reg_cmd_t		*info;
+	struct BRI_priv_data	*priv;
+
+	if(!xpd)
+		return -ENODEV;
+	priv = xpd->priv;
+	BUG_ON(!priv);
+	spin_lock_irqsave(&xpd->lock, flags);
+	info = &priv->last_reply;
+	len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+	len += sprintf(page + len, "# Consult firmware docs first\n");
+	len += sprintf(page + len, "#\n");
+	if(REG_FIELD(info, do_subreg)) {
+		len += sprintf(page + len, "#CH\tOP\tReg.\tSub\tDL\n");
+		len += sprintf(page + len, "%2d\tRS\t%02X\t%02X\t%02X\n",
+				REG_FIELD(info, chipsel),
+				REG_FIELD(info, regnum), REG_FIELD(info, subreg), REG_FIELD(info, data_low));
+	} else {
+		len += sprintf(page + len, "#CH\tOP\tReg.\tDL\n");
+		len += sprintf(page + len, "%2d\tRD\t%02X\t%02X\n",
+				REG_FIELD(info, chipsel),
+				REG_FIELD(info, regnum), REG_FIELD(info, data_low));
+	}
+	spin_unlock_irqrestore(&xpd->lock, flags);
+	if (len <= off+count)
+		*eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len > count)
+		len = count;
+	if (len < 0)
+		len = 0;
+	return len;
+}
+
+int __init card_bri_startup(void)
+{
+	DBG("\n");
+
+	INFO("%s revision %s\n", THIS_MODULE->name, XPP_VERSION);
+	xproto_register(&PROTO_TABLE(BRI_NT));
+	xproto_register(&PROTO_TABLE(BRI_TE));
+	return 0;
+}
+
+void __exit card_bri_cleanup(void)
+{
+	DBG("\n");
+	xproto_unregister(&PROTO_TABLE(BRI_NT));
+	xproto_unregister(&PROTO_TABLE(BRI_TE));
+}
+
+MODULE_DESCRIPTION("XPP BRI Card Driver");
+MODULE_AUTHOR("Oron Peled <oron at actcom.co.il>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(XPP_VERSION);
+MODULE_ALIAS_XPD(XPD_TYPE_BRI_NT);
+MODULE_ALIAS_XPD(XPD_TYPE_BRI_TE);
+
+module_init(card_bri_startup);
+module_exit(card_bri_cleanup);

Added: zaptel/trunk/xpp/card_bri.h
===================================================================
--- zaptel/trunk/xpp/card_bri.h	2007-02-08 21:53:33 UTC (rev 3126)
+++ zaptel/trunk/xpp/card_bri.h	2007-02-10 02:19:35 UTC (rev 3127)
@@ -0,0 +1,40 @@
+#ifndef	CARD_BRI_H
+#define	CARD_BRI_H
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2006, Xorcom
+ *
+ * All rights reserved.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "xpd.h"
+
+enum bri_opcodes {
+	XPROTO_NAME(BRI, REGISTER_REQUEST)		= 0x0F,
+	XPROTO_NAME(BRI, REGISTER_REPLY)		= 0x10,
+	XPROTO_NAME(BRI, SET_LED)			= 0x33,
+};
+
+DEF_RPACKET_DATA(BRI, REGISTER_REPLY,	/* Get status of a single register (for debugging) */
+	reg_cmd_t	regcmd;
+	);
+DEF_RPACKET_DATA(BRI, REGISTER_REQUEST,
+	reg_cmd_t	reg_cmd;
+	);
+
+#endif	/* CARD_BRI_H */




More information about the Pkg-voip-commits mailing list