[svn-commits] tzafrir: branch 1.4 r4641 - in /branches/1.4: ./ kernel/xpp/ kernel/xpp/firmw...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed May 27 05:01:29 CDT 2009
Author: tzafrir
Date: Wed May 27 05:01:24 2009
New Revision: 4641
URL: http://svn.asterisk.org/svn-view/zaptel?view=rev&rev=4641
Log:
Big dump of newer xpp code.
For finer details and separate commits, you are advised to look into the
commit log of dahdi-{linux,tools}.
xpp.r7150
* 116x Astribanks:
- Support for the TwinStar capability and for FXO and (BRI|PRI) on
same device.
- New control protocol ("MPP").
- astribank_hextool - a low-level firmware loading tool instead of
fpga_load .
- astribank_tool - Other MPP activities .
- Can still reset (but just that) through older protocol.
- astribank_hexload is required for loading FPGA firmware for USB_FW.hex
rev > 6885.
- USB_FW rev. 7071 .
- More modular FPGA firmware (1161 only).
- FPGA_1161.hex rev. 7131. PIC_TYPE_* rev. 7107.
- software-settings of some capabilities with astribank_allow .
* XPP:
- init_card_* script are less verbose.
- Reduced rate of "Is a DAHDI sync master" message.
- Replace member bus_id with dev_name() and set_dev_name() for
building with 2.6.30.
- Conditionally remove 'owner' property of procfs was dropped in 2.6.30.
- astribank_hook now enabled by default.
- Has an optional hook for TwinStar.
* BRI:
- hardhdlc support: The bri_dchan patch is no longer needed.
- If bri_dchan patch applied: old code is used, and "dchan" is used.
- If not: new code and "hardhdlc" is used.
- zapconf will generate the right configuration, depending on the new
sysfs driver attribute bri_hardhdlc, but default to "dchan" as
before if not explicitly told.
- Bugfix: explicitly turn off leds on startup.
* FXS:
- Initialization and calibration fixes.
- Notify the user just one about wrong VMWI config
* Dahdi-perl:
- Fix detection of empty slots in wctdm.
- Fix working with ethmf's extra file in /proc/zaptel
- Improved detection of Rhino cards.
- dahdi_genconf's generated text better explains files are generated.
- /etc/xpp_order - allow specifiying an explicit order for
Astribanks to register with Zaptel.
- Dahdi::Xpp::Mpp - A wrapper around astribank_tool .
* dahdi.init:
- A separate waitfor_xpds script. May now have a wait-loop in
some cases.
- xpp_sync needs to only be called after dahdi_cfg .
(for the PRI module).
Added:
branches/1.4/kernel/xpp/firmwares/FPGA_1161.hex (with props)
branches/1.4/kernel/xpp/firmwares/PIC_TYPE_1.hex (with props)
branches/1.4/kernel/xpp/firmwares/PIC_TYPE_2.hex (with props)
branches/1.4/kernel/xpp/firmwares/PIC_TYPE_3.hex (with props)
branches/1.4/kernel/xpp/firmwares/PIC_TYPE_4.hex (with props)
branches/1.4/kernel/xpp/utils/astribank_allow.c (with props)
branches/1.4/kernel/xpp/utils/astribank_hexload.8 (with props)
branches/1.4/kernel/xpp/utils/astribank_hexload.c (with props)
branches/1.4/kernel/xpp/utils/astribank_tool.8 (with props)
branches/1.4/kernel/xpp/utils/astribank_tool.c (with props)
branches/1.4/kernel/xpp/utils/astribank_usb.c (with props)
branches/1.4/kernel/xpp/utils/astribank_usb.h (with props)
branches/1.4/kernel/xpp/utils/debug.c (with props)
branches/1.4/kernel/xpp/utils/debug.h (with props)
branches/1.4/kernel/xpp/utils/mpp.h (with props)
branches/1.4/kernel/xpp/utils/mpp_funcs.c (with props)
branches/1.4/kernel/xpp/utils/mpp_funcs.h (with props)
branches/1.4/kernel/xpp/utils/pic_loader.c (with props)
branches/1.4/kernel/xpp/utils/pic_loader.h (with props)
branches/1.4/kernel/xpp/utils/twinstar (with props)
branches/1.4/kernel/xpp/utils/twinstar_hook (with props)
branches/1.4/kernel/xpp/utils/twinstar_setup (with props)
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Xpporder.pm (with props)
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Xpp/Mpp.pm (with props)
Modified:
branches/1.4/kernel/xpp/.version
branches/1.4/kernel/xpp/Changelog_xpp
branches/1.4/kernel/xpp/Kbuild
branches/1.4/kernel/xpp/README.Astribank
branches/1.4/kernel/xpp/card_bri.c
branches/1.4/kernel/xpp/card_fxo.c
branches/1.4/kernel/xpp/card_fxs.c
branches/1.4/kernel/xpp/card_global.c
branches/1.4/kernel/xpp/card_pri.c
branches/1.4/kernel/xpp/firmwares/USB_FW.hex
branches/1.4/kernel/xpp/init_card_1_30
branches/1.4/kernel/xpp/init_card_2_30
branches/1.4/kernel/xpp/init_card_3_30
branches/1.4/kernel/xpp/init_card_4_30
branches/1.4/kernel/xpp/utils/Makefile
branches/1.4/kernel/xpp/utils/genconf_parameters
branches/1.4/kernel/xpp/utils/hexfile.c
branches/1.4/kernel/xpp/utils/hexfile.h
branches/1.4/kernel/xpp/utils/lszaptel
branches/1.4/kernel/xpp/utils/xpp.rules
branches/1.4/kernel/xpp/utils/xpp_fxloader
branches/1.4/kernel/xpp/utils/xpp_sync
branches/1.4/kernel/xpp/utils/zapconf
branches/1.4/kernel/xpp/utils/zaptel_drivers
branches/1.4/kernel/xpp/utils/zaptel_hardware
branches/1.4/kernel/xpp/utils/zconf/Zaptel.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Chans.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Unicall.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Users.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zapata.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Gen/Zaptel.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Config/Params.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Hardware.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Hardware/PCI.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Hardware/USB.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Span.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Xpp.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Xpp/Xbus.pm
branches/1.4/kernel/xpp/utils/zconf/Zaptel/Xpp/Xpd.pm
branches/1.4/kernel/xpp/utils/zt_registration
branches/1.4/kernel/xpp/xbus-core.c
branches/1.4/kernel/xpp/xbus-core.h
branches/1.4/kernel/xpp/xbus-pcm.c
branches/1.4/kernel/xpp/xbus-sysfs.c
branches/1.4/kernel/xpp/xdefs.h
branches/1.4/kernel/xpp/xpd.h
branches/1.4/kernel/xpp/xpp.conf
branches/1.4/kernel/xpp/xpp_usb.c
branches/1.4/kernel/xpp/xpp_zap.c
branches/1.4/kernel/xpp/xpp_zap.h
branches/1.4/kernel/xpp/xproto.c
branches/1.4/kernel/xpp/xproto.h
branches/1.4/zaptel.init
Modified: branches/1.4/kernel/xpp/.version
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/.version?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/.version (original)
+++ branches/1.4/kernel/xpp/.version Wed May 27 05:01:24 2009
@@ -1,1 +1,1 @@
-branch-rel-6839-r6908
+trunk-r7150
Modified: branches/1.4/kernel/xpp/Changelog_xpp
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/Changelog_xpp?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/Changelog_xpp (original)
+++ branches/1.4/kernel/xpp/Changelog_xpp Wed May 27 05:01:24 2009
@@ -1,3 +1,51 @@
+Wed May 27 2009 Oron Peled <oron at actcom.co.il> - xpp.r7150
+ * 116x Astribanks:
+ - Support for the TwinStar capability and for FXO and (BRI|PRI) on
+ same device.
+ - New control protocol ("MPP").
+ - astribank_hextool - a low-level firmware loading tool instead of
+ fpga_load .
+ - astribank_tool - Other MPP activities .
+ - Can still reset (but just that) through older protocol.
+ - astribank_hexload is required for loading FPGA firmware for USB_FW.hex
+ rev > 6885.
+ - USB_FW rev. 7071 .
+ - More modular FPGA firmware (1161 only).
+ - FPGA_1161.hex rev. 7131. PIC_TYPE_* rev. 7107.
+ - software-settings of some capabilities with astribank_allow .
+ * XPP:
+ - init_card_* script are less verbose.
+ - Reduced rate of "Is a DAHDI sync master" message.
+ - Replace member bus_id with dev_name() and set_dev_name() for
+ building with 2.6.30.
+ - Conditionally remove 'owner' property of procfs was dropped in 2.6.30.
+ - astribank_hook now enabled by default.
+ - Has an optional hook for TwinStar.
+ * BRI:
+ - hardhdlc support: The bri_dchan patch is no longer needed.
+ - If bri_dchan patch applied: old code is used, and "dchan" is used.
+ - If not: new code and "hardhdlc" is used.
+ - zapconf will generate the right configuration, depending on the new
+ sysfs driver attribute bri_hardhdlc, but default to "dchan" as
+ before if not explicitly told.
+ - Bugfix: explicitly turn off leds on startup.
+ * FXS:
+ - Initialization and calibration fixes.
+ - Notify the user just one about wrong VMWI config
+ * Dahdi-perl:
+ - Fix detection of empty slots in wctdm.
+ - Fix working with ethmf's extra file in /proc/zaptel
+ - Improved detection of Rhino cards.
+ - dahdi_genconf's generated text better explains files are generated.
+ - /etc/xpp_order - allow specifiying an explicit order for
+ Astribanks to register with Zaptel.
+ - Dahdi::Xpp::Mpp - A wrapper around astribank_tool .
+ * dahdi.init:
+ - A separate waitfor_xpds script. May now have a wait-loop in
+ some cases.
+ - xpp_sync needs to only be called after dahdi_cfg .
+ (for the PRI module).
+
Sun Mar 1 2009 Oron Peled <oron at actcom.co.il> - xpp.r6795
* Fix cases where the command_queue overflowed during initialization.
- Also add a 'command_queue_length' parameter to xpp.ko
@@ -21,9 +69,9 @@
For sites that get non-standard power-denial signals from central
office on offhook.
- Don't hangup on power-denial, just notify Dahdi and wait for
+ Asterisk's desicion.
- Fix caller-id detection for the case central office sends it before
first ring without any indication before.
- Asterisk's desicion.
* New USB_FW.hex (xpp.r6885): handles some firmware rewriting races.
Mon, Dec 8 2008 Oron Peled <oron at actcom.co.il> - xpp.r6430
Modified: branches/1.4/kernel/xpp/Kbuild
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/Kbuild?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/Kbuild (original)
+++ branches/1.4/kernel/xpp/Kbuild Wed May 27 05:01:24 2009
@@ -13,11 +13,8 @@
-g # -DOLD_PROC
#
-ifneq (,$(shell grep -w echo_can_state_t $(ZAP_KERNEL)/zaptel.h))
-EXTRA_CFLAGS += -DZAPTEL_EC_TYPEDEF
-endif
-obj-m += xpp.o xpd_fxs.o xpd_fxo.o xpd_pri.o
+obj-m += xpp.o xpd_fxs.o xpd_fxo.o xpd_bri.o xpd_pri.o
HAS_BRISTUFF := $(shell grep -c '^[[:space:]]*\#[[:space:]]*define[[:space:]]\+CONFIG_ZAPATA_BRI_DCHANS\>' $(ZAP_KERNEL)/zconfig.h)
@@ -25,15 +22,12 @@
ifneq (,$(filter y m,$(CONFIG_USB)))
obj-m += xpp_usb.o
endif
-ifneq (0,$(HAS_BRISTUFF))
-obj-m += xpd_bri.o
-endif
-xpp-y += xbus-core.o xbus-sysfs.o xbus-pcm.o xframe_queue.o xpp_zap.o xproto.o card_global.o zap_debug.o
-xpd_fxs-y += card_fxs.o
-xpd_fxo-y += card_fxo.o
-xpd_bri-y += card_bri.o
-xpd_pri-y += card_pri.o
+xpp-objs += xbus-core.o xbus-sysfs.o xbus-pcm.o xframe_queue.o xpp_zap.o xproto.o card_global.o zap_debug.o
+xpd_fxs-objs += card_fxs.o
+xpd_fxo-objs += card_fxo.o
+xpd_bri-objs += card_bri.o
+xpd_pri-objs += card_pri.o
ifeq (y,$(PARPORT_DEBUG))
EXTRA_CFLAGS += -DDEBUG_SYNC_PARPORT
@@ -53,5 +47,28 @@
fi
$(Q)rm -f $@.tmp
+# Validations:
+# - Syntactic verification of perl scripts
+# - Handle country table validation for init_card_2_*
+
+XPP_PROTOCOL_VERSION := $(shell grep XPP_PROTOCOL_VERSION $(src)/xproto.h | sed -e 's/^.*XPP_PROTOCOL_VERSION[ \t]*//')
+
+xpp_verifications = \
+ init_card_1_$(XPP_PROTOCOL_VERSION) \
+ init_card_2_$(XPP_PROTOCOL_VERSION) \
+ init_card_3_$(XPP_PROTOCOL_VERSION) \
+ init_card_4_$(XPP_PROTOCOL_VERSION)
+
+xpp_verified = $(foreach file, $(xpp_verifications), $(file).verified)
+
+
+always := $(xpp_verified)
+
+clean-files += $(xpp_verified)
+
+$(obj)/init_card_%_$(XPP_PROTOCOL_VERSION).verified: $(src)/init_card_%_$(XPP_PROTOCOL_VERSION)
+ @echo ' VERIFY $<'
+ $(Q)perl -c $< 2> $@ || (cat $@; rm -f $@; exit 1)
+
.PHONY: FORCE
FORCE:
Modified: branches/1.4/kernel/xpp/README.Astribank
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/README.Astribank?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/README.Astribank (original)
+++ branches/1.4/kernel/xpp/README.Astribank Wed May 27 05:01:24 2009
@@ -57,6 +57,11 @@
Patch for BRI
~~~~~~~~~~~~~
+(In latest SVN version of Zaptel this patch is no longer needed. Furthermore, it does
+not apply. The same directory has a newer patch that applies. This
+section is kept in the document for the time being for the benefit of
+those with older versions)
+
In order for the BRI module (xpd_bri.ko) to build, you still need an
external patch:
@@ -77,7 +82,7 @@
~~~~~~~~~~~~~~~~~~~~~~
Below are some commented sequences of commands that can be used at some
common scenarios. Those scenarios begin only after you installed the
-software (Zaptel, asterisk, etc.).
+software (zaptel, asterisk, etc.).
New Installation Scenario
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,6 +215,69 @@
#fxs_skip_calib 1
-----------------------------------------------------------
+xpp_order: Explicitly order Astribanks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+(This feature is available in latest Zaptel SVN)
+
+On a system with multiple Astribank you would normally want to guarantee
+that Astribanks are registered in the same order regardless of the order
+in which they are connected or detected. Assuming that you register them
+all at the same time. In order to do that, you should list the
+Astribanks explicitly under /etc/xpp_order .
+
+Astribanks that are listed there are registered first (according to the
+order of lines in the files). Astribanks not listed there are added
+last, and sorted by the 'USB connector' string.
+
+You can identify an Astribank in two ways:
+
+Label::
+ each Astribank (except some really old ones) has a label . This
+ identifies the actual Astribank box.
+
+Connector::
+ Identify the path the Astribank is connected through. E.g.: to what
+ USB port you connected it.
+
+Identifying an Astribank by the label seems simpler and more
+predictable. Though it may have some slightly surprising effects if
+replace one Astribank with another.
+
+The sample configuration file:
+-----------------------------------------------------------
+#
+# This is an optional configuration file for ordering
+# Zaptel registration.
+#
+# It is read from /etc/xpp_order. This location
+# may be overriden via the environment variable XPPORDER_CONF
+#
+# Lines may contain:
+# - The Astribank label (verbatim)
+# - The Astribank connector string (prefixed with @)
+# Ordering number of each listed Astribank is determined
+# by its position in this file.
+# Astribanks not listed in this file, get an ordering
+# number of 99 (last).
+#
+# Astribanks with same ordering number are sorted by their
+# connectors (to preserve legacy behaviour).
+#
+# Examples:
+#usb:1234
+#@usb-0000:06:02.2-2
+-----------------------------------------------------------
+
+
+In order to generate one that includes all the Astribanks in the system
+with the current order in which they are connected, use:
+
+ zapconf xpporder
+
+For more technical details see the section <<_registering_in_zaptel>>
+below.
+
+
/etc/zaptel.conf
~~~~~~~~~~~~~~~~
@@ -237,7 +305,9 @@
span=3,2,1,ccs,ami
span=4,0,1,ccs,ami
bchan=1-2,4-5,7-8,10-11
- dchan=3,6,9,12
+ ; if you applied the bri_dchan patch:
+ ;dchan=3,6,9,12
+ hardhdlc=3,6,9,12
Astribank 4 PRI E1
^^^^^^^^^^^^^^^^^^
@@ -865,7 +935,7 @@
driver / zaptel.
span::
- Dahdi breaks the channels it knows about to logical units called
+ Zaptel breaks the channels it knows about to logical units called
"spans". A port in a E1/T1/ISDN card is usually a span. An whole
analog card is also a "span". You can see the list of spans as the list
of files under /proc/zaptel directory or in output of the dahdi_tool
@@ -876,7 +946,7 @@
XPD::
Basically this is a logical unit of the Astribank. It will be
- registered in Dahdi as a single span. This can be either an analog
+ registered in Zaptel as a single span. This can be either an analog
(FXS or FXO) module or a single port in case of a BRI module.
@@ -897,30 +967,31 @@
The Astribank needs a firmware loaded into it. Without the firmware,
the device will appear in lsusb with Vendor ID e4e4 and Product ID 11x0
-(1130, 1140 or 1150). The firmware loading process consists of two stages.
-In the first stage the "USB" firmware is loaded by using program fxload.
-When the first stage is completed the Vendor ID is e4e4 and the Product ID
-is 11x1. (e.g. 1151 if it were 1150 previously).
+(1130, 1140, 1150 or 1160). The firmware loading process consists of two
+stages. In the first stage the "USB" firmware is loaded by using program
+fxload. When the first stage is completed the Vendor ID is e4e4 and the
+Product ID is 11x1. (e.g. 1151 if it were 1150 previously).
You can use the following command in order to load the "USB" firmware
manually:
- fxload -t fx2 -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_FW.hex
+ fxload -t fx2 -D /dev/bus/usb/MMM/NNN -I /usr/share/zaptel/USB_FW.hex
where,
fxload::
A standard program that is typically part either of package 'fxload'
or 'hotplug-utils' .
-/proc/bus/usb::
- The mount point of the USB file-system (usbfs).
+/dev/bus/usb::
+ On some old systems it is missing . /proc/bus/usb (usbfs) could be
+ used instead.
MMM::
the first number (bus number)
NNN::
the second number (device number) you see for the device in lsusb
If the loading process has been completed successfully, the device
-disconnects and then connects again itself with USB Product ID 1131
+disconnects and then connects again itself with USB Product ID 11x1
(and a new device number).
In the second stage, the "FPGA" firmware is loaded.
@@ -931,7 +1002,20 @@
The command syntax is similar to the syntax of fxload. You can use the
following command in order to load the FPGA firmware manually:
- fpga_load -D /proc/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_1151.hex
+ # pick the right name according to the device ID. FPGA_1161.hex is for
+ # 116x Astribanks:
+ astribank_hexload -D /dev/bus/usb/MMM/NNN -F /usr/share/zaptel/FPGA_1161.hex
+ # Note the shell expantion in this line:
+ astribank_hexload -D /dev/bus/usb/MMM/NNN -p /usr/share/zaptel/PIC_TYPE_[1-4].hex
+ # reenumerate (disconnect and reconnect)
+ astribank_tool -D /dev/bus/usb/MMM/NNN -n
+
+With older USB firmwares before the one included in DAHDI 2.2 or latest
+Zaptel SVN, you needed to use instead of all the above:
+
+ # pick the right name according to the device ID. FPGA_1151.hex is for
+ # 115x Astribanks:
+ fpga_load -D /dev/bus/usb/MMM/NNN -I /usr/share/zaptel/FPGA_1151.hex
Please note, that NNN value differs from that that was used for the
fxload command due to the fact that device has "reconnected" itself
@@ -939,9 +1023,8 @@
the new NNN value. Usually, the new value is equal to the old value
incremented by 1.
-On newer systems usbfs (/prob/bus/usb) is replaced by basically the same
-structure under /dev/bus/usb . Note, however, that zaptel_hardware still
-relies on some data from usbfs that is not found in /dev/usb .
+On newer systems (e.g. Centos 4) /dev/bus/usb may not be available. In
+that case, use /proc/bus/usb . usbfs should be mounted there.
Automatic Firmware Loading
@@ -985,6 +1068,14 @@
INFO-xpp_usb: XUSB: Xorcom LTD -- Astribank -- FPGA
-------------------------------------
+Another useful tool for tracing UDEV-related issue is the udev monitor:
+
+ udevadm monitor
+
+Or with some older versions of udev:
+
+ udevmonitor
+
Firmware Loading with Hotplug
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1007,7 +1098,7 @@
Here is what should happen:
In short: you should plug the Astribank device(s) or have them plugged in at
the boot time. Then all the modules should be loaded automatically.
-You will see xpp_usb , xpd_fxs and, possibly, xpd_fxo in the modules list
+You will see xpp_usb, xpp, and some xpd_* modules in the modules list
(the output of lsmod).
After the module xpp is loaded, you'll also be able to see the directory
@@ -1021,7 +1112,7 @@
The driver of the Astribank is composed of several modules:
xpp::
- The basic module, that communicates with Dahdi and provides some
+ The basic module, that communicates with Zaptel and provides some
common services to other modules.
xpd_fxs::
FXS modules (analog phones). Module type 1.
@@ -1039,7 +1130,7 @@
xpd_fxo if you have only Astribank FXS.
Once an Astribank device connected and the firmware is loaded, the
-Vendor-ID/Product-ID of the device will be e4e4/1132 . The handler for that
+Vendor-ID/Product-ID of the device will be e4e4/11x2 . The handler for that
combination is listed as the kernel module xpp_usb. Therefore, the system
runs 'modprobe xpp_usb' if that module is not already loaded.
@@ -1075,7 +1166,13 @@
NOTICE-xpp: XBUS-00: CARD 0: missing protocol table for type 3. Ignored.
--------------------------------------------------
In this case it was because I maliciously removed the module xpd_bri
-(type 3) from the system.
+(type 3) from the system.
+
+This can also happen if you accidentally blacklist the relevant xpd-*
+module. 'blacklist some_module' in modprobe.conf or modprobe.d/*.conf
+means that a direct insmod or modprobe of their name will work, but any
+attempt to load a module through its aliases will fail. Recall that the
+cpd-* modules are loaded on-demand using the alias 'xpd-type-N' .
Device Initializations Scripts
@@ -1111,11 +1208,8 @@
When the Astribank has finished initialization it also notifies
userspace applications. This can be used to run a custom command when an
Astribank is connected (after it has finished initialization) or when it
-has disconnected.
-
-To use that you need to comment-out the last line in the udev rules file
-xpp.rules. A sample hook script is included in
-kernel/xpp/utils/astribank_hook.sample .
+has disconnected. The hook script is installed by default to
+/usr/share/zaptel/astribank_hook .
Registering in Zaptel
@@ -1136,7 +1230,7 @@
For a system with several spans you'll see a "fast train of lights".
-"If you have multiple Astribank devices, zt_registration will
+If you have multiple Astribank devices, zt_registration will
register them by the ascending order of the USB connector ID. This
means that as long as the same Astribank is connected to the same
port, the order of plugging is not important.
@@ -1161,11 +1255,13 @@
If you have multiple Astribank devices, dahdi_registration will register
them by the order of the "connector" field. This means that as long as
the same Astribank is connected to the same port, the order of plugging
-is not important.
+is not important. Alternatively you can set an explicit registration
+order using /etc/dahdi/xpp_order . See above in section about
+<<_xpp_order_explicitly_order_astribanks,xpp_order>>.
The registration is performed through the sysfs interface. See below
<<_sys_devices_xpp_xbus_nn_nn_m_p_span,the span attribute>>. Also note
-that dahdi_registration also allows you to unregister spans, which will
+that zt_registration also allows you to unregister spans, which will
work for all spans that are not in use (That is: none of their channels
is in use).
@@ -1185,6 +1281,19 @@
options xpp zap_autoreg=1
+Astribanks Synchronization Source
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+If there is more than one Astribank on the system, all the Astribanks
+keep their clock in sync. Optionally the Astribanks can synchronize
+their clock to the master Zaptel device (in case it is a different Zaptel
+device). Normally you just use the default init.d script or run
+explicitly:
+
+ xpp_sync auto
+
+(For now see the man page of xpp_sync for more information)
+
+
Zaptel And Above
^^^^^^^^^^^^^^^^
From here you get a standard Zaptel span. The next step is to configure
@@ -1325,6 +1434,10 @@
/proc/xpp/XBUS-nn/XPD-mm/pri_info
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+(In latest SVN this file is read-only. The writetable functionality
+moved in part (E1/T1) to pri_protocol sysfs and in part (NT/TE) to
+zaptel.conf settings)
+
In addition to the usual information about the LEDs, this file also
provides useful information regarding ISDN Layer 1 and Layer 2 status.
For example, you can run the following command in order to monitor
@@ -1524,6 +1637,26 @@
handles it. One specific interesting thing is that this allows you to
easily see all the XPDs of the same type, as they are linked again
from the driver's directory.
+
+
+===== /sys/bus/astribanks/devices/xbus-NN/NN:M:P/pri_protocol
+Can have either of those two:
+
+E1::
+ Provides 31 channels, of which channel 16 is normally the D-channel.
+ Common in places outside of North America and Japan. This is the
+ default setup.
+
+T1::
+ T1 provides 24 channels. The last one is normally the D-Channel.
+ Common in North America.
+
+This can also be set by writing the strings explicitly to the file. But
+can only be done when an XPD is not a registered span.
+
+This writing is normally done by the device initialization script, based
+on the 'pri_protocol' settings in
+xref:_xpp_conf_astribank_initialization[/etc/xpp.conf] .
Useful Module Parameters
Modified: branches/1.4/kernel/xpp/card_bri.c
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/card_bri.c?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/card_bri.c (original)
+++ branches/1.4/kernel/xpp/card_bri.c Wed May 27 05:01:24 2009
@@ -34,10 +34,6 @@
#include "xbus-core.h"
static const char rcsid[] = "$Id$";
-
-#ifndef CONFIG_ZAPATA_BRI_DCHANS
-#error CONFIG_ZAPATA_BRI_DCHANS is not defined
-#endif
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before zap_debug.h */
static DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
@@ -131,6 +127,7 @@
#define REG30_LOST 3 /* in polls */
#define DCHAN_LOST 15000 /* in ticks */
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
#define BRI_DCHAN_SIGCAP ( \
ZT_SIG_EM | \
ZT_SIG_CLEAR | \
@@ -143,6 +140,9 @@
ZT_SIG_CAS | \
ZT_SIG_SF \
)
+#else
+#define BRI_DCHAN_SIGCAP ZT_SIG_HARDHDLC
+#endif
#define BRI_BCHAN_SIGCAP (ZT_SIG_CLEAR | ZT_SIG_DACS)
#define IS_NT(xpd) ((xpd)->direction == TO_PHONE)
@@ -212,8 +212,12 @@
/*
* D-Chan: buffers + extra state info.
*/
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
int dchan_r_idx;
byte dchan_rbuf[DCHAN_BUFSIZE];
+#else
+ atomic_t hdlc_pending;
+#endif
byte dchan_tbuf[DCHAN_BUFSIZE];
bool txframe_begin;
@@ -251,7 +255,7 @@
debug_buf[0] = '\0';
for(i = 0; i < len && n < DEBUG_BUF_SIZE; i++)
n += snprintf(&debug_buf[n], DEBUG_BUF_SIZE - n, "%02X ", buf[i]);
- XPD_DBG(GENERAL, xpd, "%s[0..%zd]: %s%s\n", msg, len-1, debug_buf,
+ XPD_NOTICE(xpd, "%s[0..%zd]: %s%s\n", msg, len-1, debug_buf,
(n >= DEBUG_BUF_SIZE)?"...":"");
}
@@ -432,6 +436,104 @@
/*
* D-Chan receive
*/
+static void bri_hdlc_abort(xpd_t *xpd, struct zt_chan *dchan, int event)
+{
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ if(debug & DBG_COMMANDS)
+ dump_hex_buf(xpd, "D-Chan(abort) RX: dchan_rbuf",
+ priv->dchan_rbuf, priv->dchan_r_idx);
+ priv->dchan_r_idx = 0;
+#else
+ zt_hdlc_abort(dchan, event);
+#endif
+}
+
+static int bri_check_stat(xpd_t *xpd, struct zt_chan *dchan, byte *buf, int len)
+{
+ struct BRI_priv_data *priv;
+ byte status;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ if(priv->dchan_r_idx < 4) {
+ XPD_NOTICE(xpd, "D-Chan RX short frame (dchan_r_idx=%d)\n",
+ priv->dchan_r_idx);
+ dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
+ bri_hdlc_abort(xpd, dchan, ZT_EVENT_ABORT);
+ return -EPROTO;
+ }
+#else
+ if(len <= 0) {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: short frame (len=%d)\n", len);
+ bri_hdlc_abort(xpd, dchan, ZT_EVENT_ABORT);
+ return -EPROTO;
+ }
+#endif
+ status = buf[len-1];
+ if(status) {
+ int event = ZT_EVENT_ABORT;
+
+ if(status == 0xFF) {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: ABORT: %d\n", status);
+ } else {
+ XPD_NOTICE(xpd, "D-Chan RX DROP: BADFCS: %d\n", status);
+ event = ZT_EVENT_BADFCS;
+ }
+ dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
+ bri_hdlc_abort(xpd, dchan, event);
+ return -EPROTO;
+ }
+ return 0;
+}
+
+int bri_hdlc_putbuf(xpd_t *xpd, struct zt_chan *dchan, unsigned char *buf, int len)
+{
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ struct BRI_priv_data *priv;
+ byte *dchan_buf;
+ byte *dst;
+ int idx;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ dchan_buf = dchan->readchunk;
+ idx = priv->dchan_r_idx;
+ if(idx + len >= DCHAN_BUFSIZE) {
+ XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
+ dump_hex_buf(xpd, " current packet", buf, len);
+ dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
+ return -ENOSPC;
+ }
+ dst = dchan_buf + idx;
+ idx += len;
+ priv->dchan_r_idx = idx;
+ memcpy(dst, buf, len);
+#else
+ zt_hdlc_putbuf(dchan, buf, len);
+#endif
+ return 0;
+}
+
+void bri_hdlc_finish(xpd_t *xpd, struct zt_chan *dchan)
+{
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ dchan->bytes2receive = priv->dchan_r_idx - 1;
+ dchan->eofrx = 1;
+#else
+ zt_hdlc_finish(dchan);
+#endif
+}
+
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
{
xbus_t *xbus;
@@ -493,14 +595,8 @@
ret = -EPROTO;
goto drop;
}
- if(dchan_buf[idx-1]) {
- XPD_NOTICE(xpd, "D-Chan RX Bad checksum: [%02X:%02X=%02X] (%d)\n",
- 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;
+ if((ret = bri_check_stat(xpd, dchan, dchan_buf, idx)) < 0)
goto drop;
- }
if(debug)
dump_dchan_packet(xpd, 0, dchan_buf, idx /* - 3 */); /* Print checksum? */
/*
@@ -517,33 +613,131 @@
out:
return ret;
}
+#else
+static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
+{
+ xbus_t *xbus;
+ struct BRI_priv_data *priv;
+ byte *src;
+ struct zt_chan *dchan;
+ uint len;
+ bool eoframe;
+ 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
+ dchan = XPD_CHAN(xpd, 2);
+ if(!IS_OFFHOOK(xpd, 2)) { /* D-chan is used? */
+ static int rate_limit;
+
+ if((rate_limit++ % 1000) == 0)
+ XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ dchan->bytes2receive = 0;
+ dchan->bytes2transmit = 0;
+#endif
+ goto out;
+ }
+ XPD_DBG(GENERAL, xpd, "D-Chan RX: eoframe=%d len=%d\n", eoframe, len);
+ ret = bri_hdlc_putbuf(xpd, dchan, src, (eoframe) ? len - 1 : len);
+ if(ret < 0)
+ goto out;
+ if(!eoframe)
+ goto out;
+ if((ret = bri_check_stat(xpd, dchan, src, len)) < 0)
+ goto out;
+ /*
+ * Tell Zaptel that we received len-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(src[len-1])" above.
+ */
+ bri_hdlc_finish(xpd, dchan);
+ priv->dchan_rx_counter++;
+ priv->dchan_norx_ticks = 0;
+out:
+ return ret;
+}
+#endif
/*
* D-Chan transmit
*/
-static int tx_dchan(xpd_t *xpd)
-{
- struct BRI_priv_data *priv;
- struct zt_chan *dchan;
- int len;
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+/* ZAPTEL calls this when it has data it wants to send to the HDLC controller */
+static void bri_hdlc_hard_xmit(struct zt_chan *chan)
+{
+ xpd_t *xpd = chan->pvt;
+ struct zt_chan *dchan;
+ struct BRI_priv_data *priv;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ dchan = XPD_CHAN(xpd, 2);
+ if (dchan == chan) {
+ atomic_inc(&priv->hdlc_pending);
+ }
+}
+#endif
+
+int bri_hdlc_getbuf(struct zt_chan *dchan, unsigned char *buf, unsigned int *size)
+{
+ int len = *size;
int eoframe;
- int ret;
-
- priv = xpd->priv;
- BUG_ON(!priv);
- if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & ZT_FLAG_RUNNING))
- return 0;
- dchan = XPD_CHAN(xpd, 2);
+
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
len = dchan->bytes2transmit; /* dchan's hdlc package len */
+ if(len > *size)
+ len = *size; /* Silent truncation */
eoframe = dchan->eoftx; /* dchan's end of frame */
dchan->bytes2transmit = 0;
dchan->eoftx = 0;
dchan->bytes2receive = 0;
dchan->eofrx = 0;
+#else
+ eoframe = zt_hdlc_getbuf(dchan, buf, &len);
+#endif
+ *size = len;
+ return eoframe;
+}
+
+static int tx_dchan(xpd_t *xpd)
+{
+ struct BRI_priv_data *priv;
+ struct zt_chan *dchan;
+ int len;
+ int eoframe;
+ int ret;
+
+ priv = xpd->priv;
+ BUG_ON(!priv);
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ if(atomic_read(&priv->hdlc_pending) == 0)
+ return 0;
+#endif
+ if(!SPAN_REGISTERED(xpd) || !(xpd->span.flags & ZT_FLAG_RUNNING))
+ return 0;
+ dchan = XPD_CHAN(xpd, 2);
+ len = ARRAY_SIZE(priv->dchan_tbuf);
+ if(len > MULTIBYTE_MAX_LEN)
+ len = MULTIBYTE_MAX_LEN;
+ eoframe = bri_hdlc_getbuf(dchan, priv->dchan_tbuf, &len);
if(len <= 0)
return 0; /* Nothing to transmit on D channel */
if(len > MULTIBYTE_MAX_LEN) {
XPD_ERR(xpd, "%s: len=%d. need to split. Unimplemented.\n", __FUNCTION__, len);
+ dump_hex_buf(xpd, "D-Chan TX:", priv->dchan_tbuf, len);
return -EINVAL;
}
if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
@@ -552,7 +746,6 @@
te_activation(xpd, 1);
else
nt_activation(xpd, 1);
- return 0;
}
if(debug)
dump_dchan_packet(xpd, 1, priv->dchan_tbuf, len);
@@ -565,8 +758,12 @@
eoframe, priv->dchan_tbuf, len);
if(ret < 0)
XPD_NOTICE(xpd, "%s: failed sending xframe\n", __FUNCTION__);
- if(eoframe)
+ if(eoframe) {
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ atomic_dec(&priv->hdlc_pending);
+#endif
priv->dchan_tx_counter++;
+ }
priv->dchan_notx_ticks = 0;
return ret;
}
@@ -610,11 +807,16 @@
return -EINVAL;
}
-static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *BRI_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels = min(3, CHANNELS_PERXPD);
+ if(subunit_ports != 1) {
+ XBUS_ERR(xbus, "Bad subunit_ports=%d\n", subunit_ports);
+ return NULL;
+ }
XBUS_DBG(GENERAL, xbus, "\n");
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct BRI_priv_data), proto_table, channels);
if(!xpd)
@@ -636,6 +838,8 @@
BUG_ON(!xpd);
XPD_DBG(GENERAL, xpd, "\n");
priv = xpd->priv;
+ DO_LED(xpd, GREEN_LED, BRI_LED_OFF);
+ DO_LED(xpd, RED_LED, BRI_LED_OFF);
set_bri_timer(xpd, "T1", &priv->t1, HFC_TIMER_OFF);
write_state_register(xpd, 0); /* Enable L1 state machine */
priv->initialized = 1;
@@ -685,26 +889,33 @@
cur_chan->pvt = xpd;
if(i == 2) { /* D-CHAN */
cur_chan->sigcap = BRI_DCHAN_SIGCAP;
+ cur_chan->flags &= ~ZT_FLAG_HDLC;
+ priv->txframe_begin = 1;
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
+ priv->dchan_r_idx = 0;
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
+#else
+ atomic_set(&priv->hdlc_pending, 0);
+#endif
+ } else {
cur_chan->sigcap = BRI_BCHAN_SIGCAP;
+ }
}
CALL_XMETHOD(card_pcm_recompute, xbus, xpd, 0);
xpd->span.spanconfig = bri_spanconfig;
xpd->span.chanconfig = bri_chanconfig;
xpd->span.startup = bri_startup;
xpd->span.shutdown = bri_shutdown;
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ xpd->span.hdlc_hard_xmit = bri_hdlc_hard_xmit;
+#endif
return 0;
}
@@ -932,6 +1143,8 @@
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
{
+ /* Clear D-Channel pending data */
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
struct zt_chan *chan = XPD_CHAN(xpd, pos);
/* Clear D-Channel pending data */
@@ -939,6 +1152,7 @@
chan->eofrx = 0;
chan->bytes2transmit = 0;
chan->eoftx = 0;
+#endif
if(pos == 2) {
LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n");
BIT_CLR(xpd->offhook_state, 0);
@@ -1033,7 +1247,9 @@
*
* Don't Get Mad, Get Even: Now we override zaptel :-)
*/
+#ifdef CONFIG_ZAPATA_BRI_DCHANS
dchan->flags |= ZT_FLAG_BRIDCHAN;
+#endif
dchan->flags &= ~ZT_FLAG_HDLC;
}
return 0;
@@ -1521,6 +1737,9 @@
} else {
len += sprintf(page + len, "(dead)\n");
}
+#ifndef CONFIG_ZAPATA_BRI_DCHANS
+ len += sprintf(page + len, "hdlc_pending=%d\n", atomic_read(&priv->hdlc_pending));
+#endif
len += sprintf(page + len, "dchan_notx_ticks: %d\n", priv->dchan_notx_ticks);
len += sprintf(page + len, "dchan_norx_ticks: %d\n", priv->dchan_norx_ticks);
len += sprintf(page + len, "LED: %-10s = %d\n", "GREEN", priv->ledstate[GREEN_LED]);
@@ -1539,6 +1758,25 @@
return len;
}
+static DRIVER_ATTR_READER(dchan_hardhdlc_show, drv,buf)
+{
+ int len = 0;
+
+#if defined(CONFIG_ZAPATA_BRI_DCHANS)
+ len += sprintf(buf + len, "0\n");
+#elif defined(ZT_SIG_HARDHDLC)
+ len += sprintf(buf + len, "1\n");
+#else
+#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
+#endif
+ return len;
+}
+
+static DRIVER_ATTR(dchan_hardhdlc,S_IRUGO,dchan_hardhdlc_show,NULL);
+
+extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
+
+
static int bri_xpd_probe(struct device *dev)
{
xpd_t *xpd;
@@ -1581,7 +1819,18 @@
if((ret = xpd_driver_register(&bri_driver.driver)) < 0)
return ret;
+ ret = driver_create_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
+ if(ret < 0)
+ return ret;
INFO("revision %s\n", XPP_VERSION);
+#if defined(CONFIG_ZAPATA_BRI_DCHANS)
+ INFO("FEATURE: WITH BRISTUFF\n");
+#elif defined(ZT_SIG_HARDHDLC)
+ INFO("FEATURE: WITH HARDHDLC\n");
+#else
+#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
+#endif
+
xproto_register(&PROTO_TABLE(BRI));
return 0;
}
@@ -1590,6 +1839,7 @@
{
DBG(GENERAL, "\n");
xproto_unregister(&PROTO_TABLE(BRI));
+ driver_remove_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
xpd_driver_unregister(&bri_driver.driver);
}
Modified: branches/1.4/kernel/xpp/card_fxo.c
URL: http://svn.asterisk.org/svn-view/zaptel/branches/1.4/kernel/xpp/card_fxo.c?view=diff&rev=4641&r1=4640&r2=4641
==============================================================================
--- branches/1.4/kernel/xpp/card_fxo.c (original)
+++ branches/1.4/kernel/xpp/card_fxo.c Wed May 27 05:01:24 2009
@@ -428,7 +428,8 @@
return -EINVAL;
}
-static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table, byte subtype, int subunits, bool to_phone)
+static xpd_t *FXO_card_new(xbus_t *xbus, int unit, int subunit, const xproto_table_t *proto_table,
+ byte subtype, int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels;
@@ -440,9 +441,9 @@
return NULL;
}
[... 11084 lines stripped ...]
More information about the svn-commits
mailing list