Compare commits

..

2 Commits

Author SHA1 Message Date
Shaun Ruffell
a118a30248 Importing files for 2.5.0 release.
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/tags/2.5.0@10090 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2011-08-05 18:00:51 +00:00
Shaun Ruffell
aeed6a0268 Creating tag for the release of dahdi-linux-2.5.0
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/tags/2.5.0@10089 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2011-08-05 17:59:47 +00:00
130 changed files with 19227 additions and 75408 deletions

50
.gitignore vendored
View File

@@ -1,50 +0,0 @@
# Files that are generated as part of the build process which we do not want git
# to track.
*.[oa]
*.mod
*.mod.[oc]
*.ko
*.ko.unsigned
*.cmd
*.order
*.tar.gz
tags
cscope.*
*.symvers
*.markers
.*.o.d
README.html
modules.order
Module.markers
build_tools/checkpatch.pl
drivers/dahdi/xpp/*.verified
drivers/dahdi/.tmp_versions/
drivers/dahdi/Module.symvers
drivers/dahdi/makefw
drivers/dahdi/radfw.h
drivers/dahdi/tor2fw.h
drivers/dahdi/xpp/init_fxo_modes
drivers/dahdi/xpp/print_fxo_modes
drivers/dahdi/xpp/xpp_version.h
include/dahdi/version.h
drivers/dahdi/vpmadt032_loader/vpmadt032_loader.h
drivers/dahdi/vpmadt032_loader/vpmadt032_x86_32.o_shipped
drivers/dahdi/vpmadt032_loader/vpmadt032_x86_64.o_shipped
drivers/dahdi/firmware/dahdi-fw-hx8.bin
drivers/dahdi/firmware/dahdi-fw-oct6114-064.bin
drivers/dahdi/firmware/dahdi-fw-oct6114-128.bin
drivers/dahdi/firmware/dahdi-fw-oct6114-256.bin
drivers/dahdi/firmware/dahdi-fw-tc400m.bin
drivers/dahdi/firmware/dahdi-fw-te820.bin
drivers/dahdi/firmware/dahdi-fw-vpmoct032.bin
drivers/dahdi/firmware/dahdi-fw-a4a.bin
drivers/dahdi/firmware/dahdi-fw-a4b.bin
drivers/dahdi/firmware/dahdi-fw-a8a.bin
drivers/dahdi/firmware/dahdi-fw-a8b.bin
drivers/dahdi/firmware/dahdi-fw-oct6114-032.bin
drivers/dahdi/firmware/dahdi-fw-te133.bin
drivers/dahdi/firmware/dahdi-fw-te134.bin
drivers/dahdi/firmware/dahdi-fw-te435.bin
drivers/dahdi/firmware/make_firmware_object

1
.version Normal file
View File

@@ -0,0 +1 @@
2.5.0

4794
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,8 @@ ifeq (yes,$(HAS_KSRC))
HOTPLUG_FIRMWARE:=$(shell if grep -q '^CONFIG_FW_LOADER=[ym]' $(KCONFIG); then echo "yes"; else echo "no"; fi)
endif
UDEV_DIR:=/etc/udev/rules.d
MODULE_ALIASES:=wcfxs wctdm8xxp wct2xxp
INST_HEADERS:=kernel.h user.h fasthdlc.h wctdm_user.h dahdi_config.h
@@ -62,7 +64,17 @@ ASCIIDOC_CMD:=$(ASCIIDOC) -n -a toc -a toclevels=4
GENERATED_DOCS:=README.html
DAHDIVERSION:=$(shell build_tools/make_version . dahdi/linux)
ifneq ($(wildcard .version),)
DAHDIVERSION:=$(shell cat .version)
else
ifneq ($(wildcard .svn),)
DAHDIVERSION:=$(shell build_tools/make_version . dahdi/linux)
else
ifneq ($(wildcard .git),)
DAHDIVERSION:=$(shell build_tools/make_version . dahdi/linux)
endif
endif
endif
all: modules
@@ -85,7 +97,7 @@ prereq: include/dahdi/version.h firmware-loaders
stackcheck: $(CHECKSTACK) modules
objdump -d drivers/dahdi/*.ko drivers/dahdi/*/*.ko | $(CHECKSTACK)
install: all install-modules install-include install-firmware install-xpp-firm
install: all install-modules install-devices install-include install-firmware install-xpp-firm
@echo "###################################################"
@echo "###"
@echo "### DAHDI installed successfully."
@@ -94,7 +106,7 @@ install: all install-modules install-include install-firmware install-xpp-firm
@echo "###"
@echo "###################################################"
uninstall: uninstall-modules uninstall-include uninstall-firmware
uninstall: uninstall-modules uninstall-devices uninstall-include uninstall-firmware
install-modconf:
build_tools/genmodconf $(BUILDVER) "$(ROOT_PREFIX)" "$(filter-out dahdi dahdi_dummy xpp dahdi_transcode dahdi_dynamic,$(BUILD_MODULES)) $(MODULE_ALIASES)"
@@ -128,6 +140,14 @@ uninstall-include:
done
-rmdir $(DESTDIR)/usr/include/dahdi
install-devices:
install -d $(DESTDIR)$(UDEV_DIR)
build_tools/genudevrules > $(DESTDIR)$(UDEV_DIR)/dahdi.rules
install -m 644 drivers/dahdi/xpp/xpp.rules $(DESTDIR)$(UDEV_DIR)/
uninstall-devices:
rm -f $(DESTDIR)$(UDEV_DIR)/dahdi.rules
install-modules: modules
ifndef DESTDIR
@if modinfo zaptel > /dev/null 2>&1; then \
@@ -169,16 +189,12 @@ update:
echo "Not under version control"; \
fi
dist:
@./build_tools/make_dist "dahdi-linux" "$(DAHDIVERSION)"
clean:
ifneq (no,$(HAS_KSRC))
$(KMAKE) clean
endif
@rm -f $(GENERATED_DOCS)
$(MAKE) -C drivers/dahdi/firmware clean
$(MAKE) -C $(KSRC) M='$(PWD)/drivers/dahdi/oct612x' clean
distclean: dist-clean
@@ -201,6 +217,6 @@ README.html: README
dahdi-api.html: drivers/dahdi/dahdi-base.c
build_tools/kernel-doc --kernel $(KSRC) $^ >$@
.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm firmware-loaders dist
.PHONY: distclean dist-clean clean all install devices modules stackcheck install-udev update install-modules install-include uninstall-modules firmware-download install-xpp-firm firmware-loaders
FORCE:

518
README
View File

@@ -17,7 +17,6 @@ Digital Cards
* Digium TE405P/TE407P/TE410P/TE412P: PCI quad-port T1/E1/J1
* Digium TE220: PCI-Express dual-port T1/E1/J1
* Digium TE420: PCI-Express quad-port T1/E1/J1
* Digium TE820: PCI-Express eight-port T1/E1/J1
- wcte12xp:
* Digium TE120P: PCI single-port T1/E1/J1
* Digium TE121: PCI-Express single-port T1/E1/J1
@@ -163,24 +162,6 @@ to the script:
./build_tools/make_static_devs -d tmp/newroot/dev/dahdi
DKMS
~~~~
DKMS, Dynamic Kernel Module Support, is a framework for building Linux
kernel modules. It is used, among others, by several distributions that
package the DAHDI kernel modules.
DKMS is designed to provide updates over drivers installed from original
kernel modules tree. Thus it installed modules into /lib/modules/updates
or /lib/modules/VERSION/updates . This is generally not an issue on
normal operation. However if you try to install DAHDI from source on
a system with DAHDI installed from DKMS this way (potentially of an
older version), be sure to remove the DKMS-installed modules from the
updates directory. If you're not sure, the following command will give
you a clue of the versions installed:
find /lib/modules -name dahdi.ko
Installing the B410P drivers with mISDN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DAHDI includes the wcb4xxp driver for the B410P, however, support for the
@@ -230,10 +211,13 @@ under driver/staging/echo . In fact, dahdi_echocan_oslec assumes that
this is where the oslec code lies. If it is elsewhere you'll need to fix
the #include line.
Thus for the moment, the simplest way to build OSLEC with dahdi is to
copy the directory `drivers/staging/echo` from a recent kernel tree (at
least 2.6.28-rc1) to the a subdirectory with the same name in the
dahdi-linux tree.
Thus for the moment, the simplest way to build OSLEC with dahdi is:
1. Copy the directory `drivers/staging/echo` from a recent kernel tree
(at least 2.6.28-rc1) to the a subdirectory with the same name in the
dahdi-linux tree.
2. Edit drivers/dahdi/Kbuild and uncomment the two lines related to OSLEC.
After doing that, you'll see the following when building (running
'make')
@@ -248,15 +232,6 @@ be reported on the
https://lists.sourceforge.net/lists/listinfo/freetel-oslec[OSLEC mailing
list].
Alternatively you can also get the OSLEC code from the dahdi-linux-extra
GIT repository:
git clone git://gitorious.org/dahdi-extra/dahdi-linux-extra.git
cd dahdi-linux-extra
git archive extra-2.6 drivers/staging | (cd ..; tar xf -)
cd ..; rm -rf dahdi-linux-extra
Live Install
~~~~~~~~~~~~
In many cases you already have DAHDI installed on your system but would
@@ -445,17 +420,54 @@ reside directly under /sys/module/'module_name' .
Useful module parameters:
=== debug
(most modules)
debug (most modules)::
Sets debug mode / debug level. With most modules 'debug' can be either
disabled (0, the default value) or enabled (any other value).
+
+
wctdm and wcte1xp print several extra debugging messages if the value
of debug is more than 1.
+
+
Some modules have "debugging flags" bits - the value of debug is a
bitmask and several messages are printed if some bits are set:
- wctdm24xxp:
* 1: DEBUG_CARD
* 2: DEBUG_ECHOCAN
- wct4xxp:
* 1: DEBUG_MAIN
* 2: DEBUG_DTMF
* 4: DEBUG_REGS
* 8: DEBUG_TSI
* 16: DEBUG_ECHOCAN
* 32: DEBUG_RBS
* 64: DEBUG_FRAMER
- xpp: See also README.Astribank:
* 1: GENERAL - General debug comments.
* 2: PCM - PCM-related messages. Tend to flood logs.
* 4: LEDS - Anything related to the LEDs status control. The driver
produces a lot of messages when the option is enabled.
* 8: SYNC - Synchronization related messages.
* 16: SIGNAL - DAHDI signalling related messages.
* 32: PROC - Messages related to the procfs interface.
* 64: REGS - Reading and writing to chip registers. Tends to flood
logs.
* 128: DEVICES - Device instantiation, destruction and such.
* 256 - COMMANDS - Protocol commands. Tends to flood logs.
Sets debug mode / debug level. With most modules 'debug' can be either
disabled (0, the default value) or enabled (any other value).
deftaps (dahdi)::
The default size for the echo canceller. The number is in "taps", that
is "samples", 1/8 ms. The default is 64 - for a tail size of 8 ms.
+
+
Asterisk's chan_dahdi tends to pass its own value anyway, with a
different default size. So normally setting this doesn't change
anything.
wctdm and wcte1xp print several extra debugging messages if the value
of debug is more than 1.
Some modules have "debugging flags" bits - the value of debug is a
bitmask and several messages are printed if some bits are set:
max_pseudo_channels (dahdi)::
The maximum number of pseudo channels that dahdi will allow userspace to
create. Pseudo channels are used when conferencing channels together.
The default is 512.
To get a list of parameters supported by a module, use
@@ -463,187 +475,13 @@ To get a list of parameters supported by a module, use
Or, for a module you have just built:
modinfo ./drivers/dahdi/module_name.ko
modinfo ./module_name.ko
For the xpp modules this will also include the description and default
value of the module. You can find a list of useful xpp module parameters
in README.Astribank .
- wctdm24xxp:
* 1: DEBUG_CARD
* 2: DEBUG_ECHOCAN
- wct4xxp:
* 1: DEBUG_MAIN
* 2: DEBUG_DTMF
* 4: DEBUG_REGS
* 8: DEBUG_TSI
* 16: DEBUG_ECHOCAN
* 32: DEBUG_RBS
* 64: DEBUG_FRAMER
- xpp: See also README.Astribank:
* 1: GENERAL - General debug comments.
* 2: PCM - PCM-related messages. Tend to flood logs.
* 4: LEDS - Anything related to the LEDs status control. The driver
produces a lot of messages when the option is enabled.
* 8: SYNC - Synchronization related messages.
* 16: SIGNAL - DAHDI signalling related messages.
* 32: PROC - Messages related to the procfs interface.
* 64: REGS - Reading and writing to chip registers. Tends to flood
logs.
* 128: DEVICES - Device instantiation, destruction and such.
* 256 - COMMANDS - Protocol commands. Tends to flood logs.
+
+
The script xpp_debug in the source tree can help settting them at run
time.
=== deftaps
(dahdi)
The default size for the echo canceller. The number is in "taps", that
is "samples", 1/8 ms. The default is 64 - for a tail size of 8 ms.
Asterisk's chan_dahdi tends to pass its own value anyway, with a
different default size. So normally setting this doesn't change
anything.
=== max_pseudo_channels
(dahdi)
The maximum number of pseudo channels that dahdi will allow userspace to
create. Pseudo channels are used when conferencing channels together.
The default is 512.
=== auto_assign_spans
(dahdi)
See <<_span_assignments,Span Assignments>> below.
XPP (Astribank) module parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
==== debug
(all modules) - see above.
==== dahdi_autoreg
(xpp)
Register spans automatically (1) or not (0). Default: 0.
Setting it simplifies operations with a single Astribank and no other
DAHDI hardware. However if you have such systems, automatic
registration can cause the order of spans to be unpredictable.
The standard startup scripts use 'dahdi_registration on' instead of this.
==== tools_rootdir
(xpp)
Defaults to /. Passed (as the variable DAHDI_TOOLS_ROOTDIR) to generated
events (which can be used in udev hooks). Also serves as the base of
the variable DAHDI_INIT_DIR (by default: $DAHDI_TOOLS_DIR/usr/share/dahdi).
==== initdir
(xpp)
Deprecated. Setting both initdir and tools_rootdir will generate an error.
A directory under tools_rootdir containing the initialization scripts.
The default is /usr/share/dahdi .
Setting this value could be useful if that location is inconvenient for you.
==== rx_tasklet
(xpp)
Enable (1) or disable (0) doing most of the packets processing in
separate tasklets. This should probably help on higher-end systems with
multiple Astribanks.
==== vmwi_ioctl
(xpd_fxs)
Does userspace support VMWI notification via ioctl? Default: 1 (yes).
Disable this (0) to have the driver attempt to detect the voicemail
message waiting indication status for this port from FSK messages
userspace (Asterisk) sends. Set the ports to use AC neon-lamp style
message waiting indication. The detection from the FSK messages takes
extra CPU cycles but is required with e.g. Asterisk < 1.6.0 .
Also note that in order for this parameter to take effect, it must be
set before the span is registered. This practically means that it
should be set through modprobe.d files.
See also Voicemail Indication in README.Astribank.
==== usb1
(xpp_usb)
Enable (1) or disable (0) support of USB1 devices. Disabled by default.
USB1 devices are not well-tested. It seems that they don't work at all
for Astribank BRI. Generally they should work with the current code, but
we expect the voice quality issues. Hence we would like to make it
very clear that you if you have a USB1 port (rather than a USB2 one, as
recommended) you will have to take an action to enable the device.
==== poll intervals
(various)
There are various values which the driver occasionally polls the
device for. For instance, the parameter poll_battery_interval for
xpd_fxo to poll the battery, in order to know if the telco line is
actually connected.
The value of those parameters is typically a number in milliseconds.
0 is used to disable polling. Under normal operation there should be
no reason to play with those parameters.
==== dtmf_detection
(xpd_fxs)
Enable (1) or disable (0) support of hardware DTMF detection by the
Astribank.
==== caller_id_style
(xpd_fxo)
Various types of caller ID signalling styles require knowing the PCM
even when the line is on-hook (which is usually a waste of CPU and
bandwidth). This parameter allows fine-tuning the behaviour here:
* 0 (default) - Don't pass extra PCM when on-hook.
* 1 ETSI-FSK: Wait for polarity reversal to come before a ring and
then start passing PCM until the caller ID has been passed.
* 2 ETSI-DTMF: Always pass PCM and generate a DTMF if polarity reversal is
detected before ring.
* 3 Passthrough: Always pass PCM as-is.
This parameter is read-only. It cannot be changed at run-time.
==== battery_threshold
(xpd_fxo)
Minimum voltage that shows there is battery. Defaults to 3. Normally you
should not need to change this, unless dealing with a funky PSTN
provider.
==== battery_debounce
(xpd_fxo)
Minimum interval (msec) for detection of battery off (as opposed to e.g.
a temporary power denial to signal a hangup). Defaults to 1000. As with
battery_threshold above, there's normally no need to tweak it.
==== use_polrev_firmware
(xpd_fxo)
Enable (1, default) or disable (0) support for polarity reversal
detection in the hardware. Only has effect with PIC_TYPE_2.hex rev. >=
11039 and with the initialization changes (init_card_2_30) in rev.
949aa49.
This parameter is read-only. It cannot be changed at run-time.
Internals
---------
DAHDI Device Files
@@ -655,14 +493,9 @@ or dynamically through the udev system.
* /dev/dahdi/ctl (196:0) - a general device file for various information and
control operations on the DAHDI channels.
* /dev/dahdi/chan/N/M - A device file for channel M in span N
- Both N and M are zero padded 3 digit numbers
- Both N and M start at 001
- M is chanpos - numbering relative to the current span.
* /dev/dahdi/NNN (196:NNN) - for NNN in the range 1-249. A device file for
DAHDI channel NNN. It can be used to read data from the channel
and write data to the channel. It is not generated by default but may
be generated as a symlink using udev rules.
and write data to the channel.
* /dev/dahdi/transcode (196:250) - Used to connect to a DAHDI transcoding
device.
* /dev/dahdi/timer (196:253) - Allows setting timers. Used anywhere?
@@ -705,7 +538,6 @@ timing device it will hang forever in the first cycle. Otherwise it will just
give you in each cycle the percent of how close it was. Also try running it
with the option -v for a verbose output.
Spans and Channels
~~~~~~~~~~~~~~~~~~
DAHDI provides telephony *channels* to the userspace applications.
@@ -725,81 +557,6 @@ There are up to 128 spans and 1024 channels. This is a hard-wired limit
number fits in a 16 bits number). Channel and span numbers start at 1.
Span Assignments
~~~~~~~~~~~~~~~~
A DAHDI device (e.g. a PCI card) is represented within the DAHDI drivers
as a 'DAHDI device'. Normally (with auto_assign_spans=1 in the module
dahdi, which is the default), when a device is discovered and loaded,
it registers with the DAHDI core and its spans automatically become
available. However if you have more than one device, you may be
interested to set explicit spans and channels numbers for them. To use
manual span assigment, set 'auto_assign_spans' to 0 . e.g. in a file
under /etc/modprobe.d/ include the following line:
options dahdi auto_assign_spans=0
You will then need to assign the spans manually at device startup. You
will need to assign a span number and channel numbers for each
available span on the system. On my test system I have one BRI PCI card
and one Astribank BRI+FXS:
# grep . /sys/bus/dahdi_devices/devices/*/spantype
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:1:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:2:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:3:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:4:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:5:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:6:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:7:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:8:BRI
/sys/bus/dahdi_devices/devices/astribanks:xbus-00/spantype:9:FXS
/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/spantype:1:TE
/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/spantype:2:TE
/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/spantype:3:NT
/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/spantype:4:NT
All spans here, except the FXS one, are BRI spans with 3 channels per span.
In order to assign a span, we write three numbers separated by colns to
the file 'assign_span' in the SysFS node
local_num:span_num:base_chan_num
Thus:
echo 9:5:10 >/sys/bus/dahdi_devices/devices/astribanks:xbus-00/assign_span
echo 2:8:40 >/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/assign_span
echo 1:1:1 >/sys/bus/dahdi_devices/devices/astribanks:xbus-00/assign_span
echo 4:6:20 >/sys/bus/dahdi_devices/devices/pci:0000:00:09.0/assign_span
echo 3:2:5 >/sys/bus/dahdi_devices/devices/astribanks:xbus-00/assign_span
As you can see, the order of span numbers or local span number is
insignificant. However the order of channel numbers must be the same as
that of span numbers.
Which indeed produced:
# head -n3 -q /proc/dahdi/*
Span 1: XBUS-00/XPD-00 "Xorcom XPD [usb:LAB-0003].1: BRI_NT"
1 XPP_BRI_NT/00/00/0
Span 2: XBUS-00/XPD-02 "Xorcom XPD [usb:LAB-0003].3: BRI_TE"
5 XPP_BRI_TE/00/02/0
Span 5: XBUS-00/XPD-10 "Xorcom XPD [usb:LAB-0003].9: FXS" (MASTER)
10 XPP_FXS/00/10/0
Span 6: B4/0/4 "B4XXP (PCI) Card 0 Span 4" RED
23 B4/0/4/1 YELLOW
Span 8: B4/0/2 "B4XXP (PCI) Card 0 Span 2" RED
40 B4/0/2/1 RED
Likewise spans can be unassigned by writing to the 'unassign-span'
"file".
Dynamic Spans
~~~~~~~~~~~~~
Dynamic spans are spans that are not represented by real hardware.
@@ -887,169 +644,6 @@ see an extra '(In use)':
2 XPP_FXS/0/0/1 FXOLS (In use)
SysFS Interface
~~~~~~~~~~~~~~~
DAHDI exposes several interfaces under the SysFS virtual file system.
SysFS represents kernel objects in nodes - directories. There properties
are often files. They may also contain other nodes or include symlinks
to other nodes.
Class DAHDI
^^^^^^^^^^^
under /sys/class/dadhi there exists a node for each DAHDI device file
under /dev/dahdi. The name is 'dahdi!foo' for the file '/dev/dahdi/foo'
(udev translates exclamation marks to slashes). Those nodes are not, for
the most part, proper SysFS nodes, and don't include any interesting
properties.
Devices Bus
^^^^^^^^^^^
Each DAHDI device (a physical device, such as a PCI card) is represented
by a node under /sys/bus/dahdi_devices/devices named with the name of
its device.
Its attributes include:
===== /sys/bus/dahdi_devices/devices/DEVICE/assgin-span
Write-only attribute: this device's spans should now be assigned
("registered"). See section about <<_span_assignments>>.
===== /sys/bus/dahdi_devices/devices/DEVICE/auto-assign
Write-only attribute. Spans in the device auto-assign ("register" as in
the original interface). See section about <<_span_assignments>>.
===== /sys/bus/dahdi_devices/devices/DEVICE/hardware_id
A unique hardware-level identifier (e.g. serial number), if available.
===== /sys/bus/dahdi_devices/devices/DEVICE/manufacturer
The name of the manufacturer. Freeform-string.
===== /sys/bus/dahdi_devices/devices/DEVICE/spantype
A line for each available span: <num>:<type>. This has to be provided
here as in the case of manual assignment, userspace may need to know
it before span nodes are created.
===== /sys/bus/dahdi_devices/devices/DEVICE/spantype
Device type.
===== /sys/bus/dahdi_devices/devices/DEVICE/unassign-span
Write-only attribute: the span whose device-local number is written
should now be unassigned ("unregistered"). See section about
<<_span_assignments>>.
Spans Bus
^^^^^^^^^
Each DAHDI span is represented by a node under
/sys/bus/dahdi_spans/devices with the name 'span-N' (where N is the
number of the span). Spans of each device also reside under the node of
the device.
Useful attributes in the span node:
===== /sys/bus/dahdi_spans/devices/span-N/alarms
The alarms of the span. Currently this is a numeric representation.
This may change in the future.
===== /sys/bus/dahdi_spans/devices/span-N/basechan
The channel number of the first channel. The channel numbers of the
following channels are guaranteed to follow it.
===== /sys/bus/dahdi_spans/devices/span-N/channels
The number of the channels in the span.
===== /sys/bus/dahdi_spans/devices/span-N/desc
A free-form description of the span.
===== /sys/bus/dahdi_spans/devices/span-N/is_digital
1 if the span is digital, 0 if it isn't.
===== /sys/bus/dahdi_spans/devices/span-N/is_sync_master
1 if the span is the sync master, 0 if it isn't.
===== /sys/bus/dahdi_spans/devices/span-N/lbo
LBO setting for the channel.
===== /sys/bus/dahdi_spans/devices/span-N/lineconfig
The framing and coding of the span, for a digital span. Textual
represenation:
<B8ZS|AMI|HDB3>/<D4|ESF|CCS>[/CRC4]
===== /sys/bus/dahdi_spans/devices/span-N/local_spanno
The number of the span within the DAHDI device.
===== /sys/bus/dahdi_spans/devices/span-N/name
A concise name for this span.
===== /sys/bus/dahdi_spans/devices/span-N/spantype
A very short type string.
===== /sys/bus/dahdi_spans/devices/span-N/syncsrc
Current sync source.
==== sys/bus/dahdi_spans/drivers/generic_lowlevel/master_span
All spans in the bus are handled by a single driver. The driver has one
non-standard attribute: master_span. printing it shows the current DAHDI
master span writing a number to it forces setting this span as the master
span.
Channels Bus
^^^^^^^^^^^^
Each DAHDI channel is represented by a node under
/sys/bus/dahdi_channels/devices with the name 'dahdi!channels!N!M'
(where N is the number of the span and M is the number of the channel
in the span - chanpos). Channels of each span also reside under the node
of the span.
Useful attributes in the channel node (All attributed listed below are
read-only):
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/alarms
List of names of the current active alarms (space separated). Normally
(no alarms) empty. Example:
RED YELLOW
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/blocksize
The block size set by userspace.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/channo
The (global) channel number.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/chanpos
The channel number within the span.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/dev
Major and minor device numbers.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/ec_factory
The name of the echo canceller to be used in the channel, if one is
configured. Example:
MG2
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/ec_state
State of the echo canceller. ACTIVE: configured and inuse. INACTIVE
otherwise.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/in_use
1 if the channel is in use (was opepend by userspace), 0 otherwise.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/name
A name string for the channel
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/sig
The signalling types set for the channel. A space-separated list of
signalling types.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/sigcap
The signalling types this channel may be configured to handle. A space-
separated list of signalling types.
User-space Interface
~~~~~~~~~~~~~~~~~~~~
User-space programs can only work with DAHDI channels. The basic
@@ -1127,7 +721,7 @@ standard HDLC rate of 64k).
Low-Level Drivers
~~~~~~~~~~~~~~~~~
Low-level drivers create spans ('struct dahdi_span'). They register the
spans with the DAHDI core using 'dahdi_device_register()'.
spans with the DAHDI core using 'dahdi_register()'.
'struct dahdi_span' has a number of informative members that are updated
solely by the low-level driver:

View File

@@ -1,123 +0,0 @@
#!/bin/sh
set -e
DKMS=$(which dkms)
usage() {
echo "$(basename $0): Helper functions for DKMS (Dynamic Kernel Module Support)"
echo "Usage: $0 [add|remove|generate_conf]"
echo "Options:"
echo " remove -a : Remove all versions of DAHDI for all kernels."
echo ""
echo "Examples:"
echo ""
echo " build_tools/dkms-helper add"
echo " Installs the current version of DAHDI into the DKMS system."
echo ""
echo " build_tools/dkms-helper remove"
echo " Removes the current version of DAHDI from all kernels."
echo ""
echo " build_tools/dkms-helper generate_conf > dkms.conf"
echo " Create a dkms.conf based on the currently compiled kernel"
echo " modules. This is also done as part of add and is not"
echo " normally needed as a separate step."
echo ""
echo "NOTE: Because firmware files could be different between different"
echo "versions of DAHDI, and the firmware files are installed into the common"
echo "/lib/firmware directory, you should remove a given version of DAHDI from all"
echo "kernels before installing a new version of DAHDI to avoid potential"
echo "conflicts."
echo ""
}
generate_configuration() {
echo 'PACKAGE_NAME="dahdi-linux"'
echo "PACKAGE_VERSION=\"$(build_tools/make_version .)\""
echo 'MAKE="make KSRC=/lib/modules/${kernelver}/build"'
echo 'CLEAN="make clean"'
echo 'AUTOINSTALL="yes"'
let "module_number=0" || true
for file in $(find ./ -type f -name "*.ko"); do
MODULE_LOCATION=$(dirname $file | cut -d\/ -f 2-)
echo "BUILT_MODULE_NAME[$module_number]=\"$(basename $file .ko)\""
echo "BUILT_MODULE_LOCATION[$module_number]=\"$MODULE_LOCATION\""
echo "DEST_MODULE_LOCATION[$module_number]=\"/kernel/dahdi/$(echo $MODULE_LOCATION | cut -d\/ -f 3-)\""
let "module_number=${module_number}+1" || true
done
if [ $module_number -eq 0 ]; then
echo "WARNING: You should build the modules before generating a config." >&2
exit 1
fi
}
add() {
GIT=$(which git)
VERSION="$(build_tools/make_version .)"
if [ $(id -u) != "0" ]; then
echo "You must run $0 as root."
exit 1
fi
echo "Building for version ${VERSION}"
make > /dev/null
echo "Copying to /usr/src/dahdi-linux-${VERSION}"
if [ ! -d /usr/src/dahdi-linux-${VERSION} ]; then
if [ -d .git ]; then
${GIT} checkout-index -a --prefix=/usr/src/dahdi-linux-${VERSION}/
else
cp -f -r * /usr/src/dahdi-linux-${VERSION}/
fi
fi
make -C /usr/src/dahdi-linux-${VERSION} install-firmware firmware-loaders
build_tools/dkms-helper generate_conf > /usr/src/dahdi-linux-${VERSION}/dkms.conf
echo $VERSION > /usr/src/dahdi-linux-${VERSION}/.version
${DKMS} add -m dahdi-linux -v ${VERSION}
${DKMS} build -m dahdi-linux -v ${VERSION}
${DKMS} install --force -m dahdi-linux -v ${VERSION}
}
remove() {
if [ $(id -u) != "0" ]; then
echo "You must run $0 as root."
exit 1
fi
REMOVE_ALL=false
shift
while getopts "a" opt; do
case $opt in
a) REMOVE_ALL=true ;;
*) echo "Unknown option to remove" ; exit 1;;
esac
done
if [ $REMOVE_ALL == true ]; then
# Remove all installed dahdi versions for all kernels.
for version in $(${DKMS} status -m dahdi-linux | cut -d, -f 2 | sed -e "s/^\s\+//"); do
echo "Removing version ${version}"
${DKMS} remove -m dahdi-linux -v ${version} --all
rm -f -r /usr/src/dahdi-linux-${version}
done
else
# Just remove the version for the current tree.
GIT=$(which git)
VERSION="$(build_tools/make_version .)"
${DKMS} remove -m dahdi-linux -v ${VERSION} --all
if [ -e /usr/src/dahdi-linux-${VERSION}/dkms.conf ]; then
rm -f -r /usr/src/dahdi-linux-${VERSION}
else
echo "/usr/src/dahdi-linux-${VERSION} not a dkms dir?"
exit 1
fi
fi
}
# Run the command...
shift $(($OPTIND-1))
COMMAND=$1
case $COMMAND in
add) add $*; exit $? ;;
remove) remove $* ; exit $? ;;
generate_conf) generate_configuration; exit $? ;;
*) echo "unknown command $0" ; usage; exit 1;;
esac
exit 0

40
build_tools/genudevrules Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/sh
ver=`udevinfo -V | cut -f3 -d" "`
if [ -z "${ver}" ]; then
# Not found - try udevadm
ver=`udevadm info -V | cut -f3 -d" "`
if [ -z "${ver}" ]; then
# nobody has that old version, anyway.
ver=54
fi
fi
# udev versions prior to 055 use a single '=' for matching key values
# udev versions 055 and later support '==' for that purpose, and versions
# beyond 092 will probably make it mandatory
#
# very old versions of udev required naming rules and permissions rules to be
# in separate files, but it's not clear at what version number that changed
if [ ${ver} -gt 54 ]; then
match="=="
else
match="="
fi
cat <<EOF
# udev rules to generate the /dev/dahdi device files (if not yet provided
# by your distribution):
KERNEL${match}"dahdictl", NAME="dahdi/ctl"
KERNEL${match}"dahditranscode", NAME="dahdi/transcode"
KERNEL${match}"dahditimer", NAME="dahdi/timer"
KERNEL${match}"dahdichannel", NAME="dahdi/channel"
KERNEL${match}"dahdipseudo", NAME="dahdi/pseudo"
KERNEL${match}"dahdi[0-9]*", NAME="dahdi/%n"
# DAHDI devices with ownership/permissions for running as non-root
SUBSYSTEM${match}"dahdi", OWNER="asterisk", GROUP="asterisk", MODE="0660"
EOF

View File

@@ -61,7 +61,7 @@ export ASTRIBANK_HEXLOAD
# make sure Astribank initialization scripts are from our tree.
xpp_ARGS="$xpp_ARGS initdir=$FIRMWARE_DIR"
dahdi_ARGS="$dahdi_ARGS tools_rootdir=$DESTDIR"
#dahdi_ARGS="$dahdi_ARGS initdir=$FIRMWARE_DIR"
if [ "$DYNAMIC_LOC" = 'yes' ]; then
MODULES_LOAD="$MODULES_LOAD dahdi_dynamic dahdi_dynamic_loc"
@@ -293,10 +293,6 @@ load)
# TODO: A local copy of Asterisk, configured with dahdi_gnconf.
# doable, but trickier.
run_asterisk
if [ "$LIVE_DAHDI_FREEPBXDB" = 'yes' ]; then
GENCONF_PARAMETERS=$DESTDIR/etc/dahdi/genconf_parameters \
dahdi_genconf freepbxdb
fi
;;
genconf)
genconf

View File

@@ -1,26 +0,0 @@
#! /bin/sh
if [ "$#" -ne 2 ]; then
echo >&2 "Usage: $0 <package> <version>"
exit 1
fi
package="$1"
version="$2"
tarball_prefix="$package-$version"
echo "I: Making dist tarball for $tarball_prefix"
tarball_name="$tarball_prefix.tar.gz"
tmp_work_dir=".tmp"
tmp_version_dir="$tmp_work_dir/$tarball_prefix"
if [ "$DESTDIR" != '' ]; then
destdir="$DESTDIR/"
fi
output="$destdir$tarball_name"
mkdir -p "$tmp_version_dir"
git archive --format tar HEAD | tar xf - -C "$tmp_version_dir"
echo "$version" > "$tmp_version_dir/.version"
tar czf "$output" -C "$tmp_work_dir" "$tarball_prefix"
rm -rf "$tmp_work_dir"
echo "I: tarball is ready: '$output'"

View File

@@ -1,7 +1,7 @@
#!/bin/sh
if [ -f ${1}/.version ]; then
cat ${1}/.version
cat ${1}.version
elif [ -f ${1}/.svnrevision ]; then
echo SVN-`cat ${1}/.svnbranch`-r`cat ${1}/.svnrevision`
elif [ -d ${1}/.svn ]; then
@@ -59,7 +59,7 @@ elif [ -d ${1}/.git ]; then
MODIFIED=""
SVN_REV=`git log --pretty=full -1 | grep -F "git-svn-id:" | sed -e "s/.*\@\([^\s]*\)\s.*/\1/g"`
if [ -z "$SVN_REV" ]; then
VERSION=`git describe --tags --dirty=M 2> /dev/null | sed -e "s/^v\([0-9]\)/\1/"`
VERSION=`git describe --long --always --tags --dirty=M 2> /dev/null`
if [ $? -ne 0 ]; then
if [ "`git ls-files -m | wc -l`" != "0" ]; then
MODIFIED="M"
@@ -115,8 +115,4 @@ elif [ -d ${1}/.git ]; then
echo SVN-${RESULT##-}-r${SVN_REV}${MODIFIED}
fi
else
# Use the directory information in the absence of any other version
# information
pwd -P
fi

View File

@@ -6,36 +6,10 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH) += dahdi_dynamic_eth.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF) += dahdi_dynamic_ethmf.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o
ifdef CONFIG_PCI
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OCT612X) += oct612x/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP) += wcte12xp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE13XP) += wcte13xp.o
wcte13xp-objs := wcte13xp-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcte13xp-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcte13xp-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE43X) += wcte43x.o
wcte43x-objs := wcte43x-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcte43x-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcte43x-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCAXX) += wcaxx.o
wcaxx-objs := wcaxx-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcaxx-base.o += -I$(src)/oct612x/ -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcaxx-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM) += wctdm.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += voicebus/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP) += wcb4xxp/
@@ -46,7 +20,6 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP) += wcte11xp.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO) += wcfxo.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2) += tor2.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO) += pciradio.o
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_XPP) += xpp/
@@ -58,13 +31,14 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2) += dahdi_echocan_mg2.o
obj-m += $(DAHDI_MODULES_EXTRA)
# If you want to build OSLEC, include the code in the standard location:
# drivers/staging/echo . The DAHDI OSLEC echo canceller will be built as
# well:
ifneq (,$(wildcard $(src)/../staging/echo/echo.c))
obj-m += dahdi_echocan_oslec.o
obj-m += ../staging/echo/echo.o
endif
# Only enable this if you think you know what you're doing. This is not
# supported yet:
#obj-m += dahdi_echocan_oslec.o
#
# A quick and dirty way to build OSLEC, if you happened to place it
# yourself in the dahdi source tree. This is experimental. See README
# regarding OSLEC.
#obj-m += ../staging/echo/
CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src)
@@ -102,7 +76,7 @@ CFLAGS_dahdi_dynamic_ethmf.o := -DNEW_SKB_LINEARIZE
endif
endif
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-sysfs-chan.o dahdi-version.o
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-version.o
###############################################################################
# Find appropriate ARCH value for VPMADT032 and HPEC binary modules

6
drivers/dahdi/Makefile Normal file
View File

@@ -0,0 +1,6 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,483 +0,0 @@
/* dahdi-sysfs-chan.c
*
* Copyright (C) 2011-2012, Xorcom
* Copyright (C) 2011-2012, Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/version.h>
#define DAHDI_PRINK_MACROS_USE_debug
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <dahdi/kernel.h>
#include "dahdi.h"
#include "dahdi-sysfs.h"
/* shortcuts, for code readability */
#define MAKE_DAHDI_DEV(num, name) \
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name)
#define DEL_DAHDI_DEV(num) \
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num))
static struct class *dahdi_class;
static dev_t dahdi_channels_devt; /*!< Device number of first channel */
static struct cdev dahdi_channels_cdev; /*!< Channels chardev's */
/*
* Flags to remember what initializations already
* succeeded.
*/
static struct {
u32 channel_driver:1;
u32 channels_bus:1;
u32 cdev:1;
} should_cleanup;
#define chan_attr(field, format_string) \
static BUS_ATTR_READER(field##_show, dev, buf) \
{ \
struct dahdi_chan *chan; \
\
chan = dev_to_chan(dev); \
return sprintf(buf, format_string, chan->field); \
}
chan_attr(name, "%s\n");
chan_attr(channo, "%d\n");
chan_attr(chanpos, "%d\n");
chan_attr(blocksize, "%d\n");
#ifdef OPTIMIZE_CHANMUTE
chan_attr(chanmute, "%d\n");
#endif
static BUS_ATTR_READER(sigcap_show, dev, buf)
{
struct dahdi_chan *chan;
int len = 0;
int i;
uint sigtypes[] = {
DAHDI_SIG_FXSLS,
DAHDI_SIG_FXSGS,
DAHDI_SIG_FXSKS,
DAHDI_SIG_FXOLS,
DAHDI_SIG_FXOGS,
DAHDI_SIG_FXOKS,
DAHDI_SIG_EM,
DAHDI_SIG_CLEAR,
DAHDI_SIG_HDLCRAW,
DAHDI_SIG_HDLCFCS,
DAHDI_SIG_HDLCNET,
DAHDI_SIG_SLAVE,
DAHDI_SIG_SF,
DAHDI_SIG_CAS,
DAHDI_SIG_EM_E1,
DAHDI_SIG_DACS_RBS,
DAHDI_SIG_HARDHDLC,
DAHDI_SIG_MTP2,
};
chan = dev_to_chan(dev);
for (i = 0; i < ARRAY_SIZE(sigtypes); i++) {
uint x = chan->sigcap & sigtypes[i];
if (x == sigtypes[i])
len += sprintf(buf + len, "%s ", sigstr(x));
}
while (len > 0 && isspace(buf[len - 1])) /* trim */
len--;
len += sprintf(buf + len, "\n");
return len;
}
static BUS_ATTR_READER(sig_show, dev, buf)
{
struct dahdi_chan *chan;
chan = dev_to_chan(dev);
return sprintf(buf, "%s\n", sigstr(chan->sig));
}
static BUS_ATTR_READER(in_use_show, dev, buf)
{
struct dahdi_chan *chan;
chan = dev_to_chan(dev);
return sprintf(buf, "%d\n", test_bit(DAHDI_FLAGBIT_OPEN, &chan->flags));
}
static BUS_ATTR_READER(alarms_show, dev, buf)
{
struct dahdi_chan *chan;
int len;
chan = dev_to_chan(dev);
len = fill_alarm_string(buf, PAGE_SIZE, chan->chan_alarms);
buf[len++] = '\n';
return len;
}
static BUS_ATTR_READER(ec_factory_show, dev, buf)
{
struct dahdi_chan *chan;
int len = 0;
chan = dev_to_chan(dev);
if (chan->ec_factory)
len += sprintf(buf, "%s", chan->ec_factory->get_name(chan));
buf[len++] = '\n';
return len;
}
static BUS_ATTR_READER(ec_state_show, dev, buf)
{
struct dahdi_chan *chan;
int len = 0;
chan = dev_to_chan(dev);
if (chan->ec_factory)
len += sprintf(buf, "%sACTIVE", (chan->ec_state) ? "" : "IN");
buf[len++] = '\n';
return len;
}
static struct device_attribute chan_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(channo),
__ATTR_RO(chanpos),
__ATTR_RO(sig),
__ATTR_RO(sigcap),
__ATTR_RO(alarms),
__ATTR_RO(ec_factory),
__ATTR_RO(ec_state),
__ATTR_RO(blocksize),
#ifdef OPTIMIZE_CHANMUTE
__ATTR_RO(chanmute),
#endif
__ATTR_RO(in_use),
__ATTR_NULL,
};
static void chan_release(struct device *dev)
{
struct dahdi_chan *chan;
BUG_ON(!dev);
chan = dev_to_chan(dev);
chan_dbg(DEVICES, chan, "SYSFS\n");
}
static int chan_match(struct device *dev, struct device_driver *driver)
{
struct dahdi_chan *chan;
chan = dev_to_chan(dev);
chan_dbg(DEVICES, chan, "SYSFS\n");
return 1;
}
static struct bus_type chan_bus_type = {
.name = "dahdi_channels",
.match = chan_match,
.dev_attrs = chan_dev_attrs,
};
static int chan_probe(struct device *dev)
{
struct dahdi_chan *chan;
chan = dev_to_chan(dev);
chan_dbg(DEVICES, chan, "SYSFS\n");
return 0;
}
static int chan_remove(struct device *dev)
{
struct dahdi_chan *chan;
chan = dev_to_chan(dev);
chan_dbg(DEVICES, chan, "SYSFS\n");
return 0;
}
static struct device_driver chan_driver = {
.name = "dahdi",
.bus = &chan_bus_type,
#ifndef OLD_HOTPLUG_SUPPORT
.owner = THIS_MODULE,
#endif
.probe = chan_probe,
.remove = chan_remove
};
int chan_sysfs_create(struct dahdi_chan *chan)
{
struct device *dev;
struct dahdi_span *span;
int res;
dev_t devt;
chan_dbg(DEVICES, chan, "Creating channel %d\n", chan->channo);
if (test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
return 0;
span = chan->span;
devt = MKDEV(MAJOR(dahdi_channels_devt), chan->channo);
dev = &chan->chan_device;
memset(dev, 0, sizeof(*dev));
dev->devt = devt;
dev->bus = &chan_bus_type;
dev->parent = span->span_device;
/*
* FIXME: the name cannot be longer than KOBJ_NAME_LEN
*/
dev_set_name(dev, "dahdi!chan!%03d!%03d", span->spanno, chan->chanpos);
dev_set_drvdata(dev, chan);
dev->release = chan_release;
res = device_register(dev);
if (res) {
chan_err(chan, "%s: device_register failed: %d\n",
__func__, res);
put_device(dev);
return res;
}
set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
return 0;
}
void chan_sysfs_remove(struct dahdi_chan *chan)
{
struct device *dev = &chan->chan_device;
chan_dbg(DEVICES, chan, "Destroying channel %d\n", chan->channo);
if (!dev_get_drvdata(dev))
return;
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
return;
dev = &chan->chan_device;
BUG_ON(dev_get_drvdata(dev) != chan);
device_unregister(dev);
/* FIXME: should have been done earlier in dahdi_chan_unreg */
chan->channo = -1;
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
}
/*
* Used by dahdi_transcode.c
*/
int dahdi_register_chardev(struct dahdi_chardev *dev)
{
static const char *DAHDI_STRING = "dahdi!";
char *udevname;
udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1,
GFP_KERNEL);
if (!udevname)
return -ENOMEM;
strcpy(udevname, DAHDI_STRING);
strcat(udevname, dev->name);
MAKE_DAHDI_DEV(dev->minor, udevname);
kfree(udevname);
return 0;
}
EXPORT_SYMBOL(dahdi_register_chardev);
/*
* Used by dahdi_transcode.c
*/
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
{
DEL_DAHDI_DEV(dev->minor);
return 0;
}
EXPORT_SYMBOL(dahdi_unregister_chardev);
/*--------- Sysfs Device handling ----*/
/*
* Describe fixed device files and maintain their
* pointer so fixed_devfiles_remove() can always be called
* and work cleanly
*/
static struct {
int minor;
char *name;
void *dev; /* FIXME: wrong type because of old kernels */
} fixed_minors[] = {
{ DAHDI_CTL, "dahdi!ctl", },
{ DAHDI_TIMER, "dahdi!timer", },
{ DAHDI_CHANNEL, "dahdi!channel",},
{ DAHDI_PSEUDO, "dahdi!pseudo", },
};
/*
* Removes /dev/dahdi/{ctl,timer,channel,pseudo}
*
* It is safe to call it during initialization error handling,
* as it skips non existing objects.
*/
static void fixed_devfiles_remove(void)
{
int i;
if (!dahdi_class)
return;
for (i = 0; i < ARRAY_SIZE(fixed_minors); i++) {
void *d = fixed_minors[i].dev;
if (d && !IS_ERR(d))
dahdi_dbg(DEVICES, "Removing fixed device file %s\n",
fixed_minors[i].name);
DEL_DAHDI_DEV(fixed_minors[i].minor);
}
}
/*
* Creates /dev/dahdi/{ctl,timer,channel,pseudo}
*/
static int fixed_devfiles_create(void)
{
int i;
int res = 0;
if (!dahdi_class) {
dahdi_err("%s: dahdi_class is not initialized yet!\n",
__func__);
res = -ENODEV;
goto cleanup;
}
for (i = 0; i < ARRAY_SIZE(fixed_minors); i++) {
char *name = fixed_minors[i].name;
int minor = fixed_minors[i].minor;
void *dummy;
dahdi_dbg(DEVICES, "Making fixed device file %s\n", name);
dummy = (void *)MAKE_DAHDI_DEV(minor, name);
if (IS_ERR(dummy)) {
int res = PTR_ERR(dummy);
dahdi_err("%s: failed (%d: %s). Error: %d\n",
__func__, minor, name, res);
goto cleanup;
}
fixed_minors[i].dev = dummy;
}
return 0;
cleanup:
fixed_devfiles_remove();
return res;
}
/*
* Called during driver unload and while handling any error during
* driver load.
* Always clean any (and only) objects that were initialized (invariant)
*/
static void sysfs_channels_cleanup(void)
{
if (should_cleanup.cdev) {
dahdi_dbg(DEVICES, "removing channels cdev\n");
cdev_del(&dahdi_channels_cdev);
should_cleanup.cdev = 0;
}
if (dahdi_channels_devt) {
dahdi_dbg(DEVICES, "unregistering chrdev_region\n");
unregister_chrdev_region(dahdi_channels_devt,
DAHDI_MAX_CHANNELS);
}
fixed_devfiles_remove();
if (dahdi_class) {
dahdi_dbg(DEVICES, "Destroying DAHDI class:\n");
class_destroy(dahdi_class);
dahdi_class = NULL;
}
if (should_cleanup.channel_driver) {
dahdi_dbg(DEVICES, "Removing channel driver\n");
driver_unregister(&chan_driver);
should_cleanup.channel_driver = 0;
}
if (should_cleanup.channels_bus) {
dahdi_dbg(DEVICES, "Removing channels bus\n");
bus_unregister(&chan_bus_type);
should_cleanup.channels_bus = 0;
}
}
int __init dahdi_sysfs_chan_init(const struct file_operations *fops)
{
int res = 0;
dahdi_dbg(DEVICES, "Registering channels bus\n");
res = bus_register(&chan_bus_type);
if (res) {
dahdi_err("%s: bus_register(%s) failed. Error number %d\n",
__func__, chan_bus_type.name, res);
goto cleanup;
}
should_cleanup.channels_bus = 1;
dahdi_dbg(DEVICES, "Registering channel driver\n");
res = driver_register(&chan_driver);
if (res) {
dahdi_err("%s: driver_register(%s) failed. Error number %d",
__func__, chan_driver.name, res);
goto cleanup;
}
should_cleanup.channel_driver = 1;
dahdi_class = class_create(THIS_MODULE, "dahdi");
if (IS_ERR(dahdi_class)) {
res = PTR_ERR(dahdi_class);
dahdi_err("%s: class_create(dahi_chan) failed. Error: %d\n",
__func__, res);
goto cleanup;
}
res = fixed_devfiles_create();
if (res)
goto cleanup;
dahdi_dbg(DEVICES, "allocating chrdev_region\n");
res = alloc_chrdev_region(&dahdi_channels_devt,
0,
DAHDI_MAX_CHANNELS,
"dahdi_channels");
if (res) {
dahdi_err("%s: Failed allocating chrdev for %d channels (%d)",
__func__, DAHDI_MAX_CHANNELS, res);
goto cleanup;
}
dahdi_dbg(DEVICES, "adding channels cdev\n");
cdev_init(&dahdi_channels_cdev, fops);
res = cdev_add(&dahdi_channels_cdev, dahdi_channels_devt,
DAHDI_MAX_CHANNELS);
if (res) {
dahdi_err("%s: cdev_add() failed (%d)", __func__, res);
goto cleanup;
}
should_cleanup.cdev = 1;
return 0;
cleanup:
sysfs_channels_cleanup();
return res;
}
void dahdi_sysfs_chan_exit(void)
{
sysfs_channels_cleanup();
}

View File

@@ -1,400 +1,123 @@
/* dahdi-sysfs.c
*
* Copyright (C) 2011-2012, Xorcom
* Copyright (C) 2011-2012, Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/kernel.h>
#include <linux/version.h>
#define DAHDI_PRINK_MACROS_USE_debug
#include <dahdi/kernel.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include "dahdi.h"
#include "dahdi-sysfs.h"
/* FIXME: Move to kernel.h */
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
static char *initdir;
module_param(initdir, charp, 0444);
MODULE_PARM_DESC(initdir,
"deprecated, should use <tools_rootdir>/usr/share/dahdi");
static char *tools_rootdir;
module_param(tools_rootdir, charp, 0444);
MODULE_PARM_DESC(tools_rootdir,
"root directory of all tools paths (default /)");
static int span_match(struct device *dev, struct device_driver *driver)
{
return 1;
}
static inline struct dahdi_span *dev_to_span(struct device *dev)
{
return dev_get_drvdata(dev);
}
#define SPAN_VAR_BLOCK \
do { \
DAHDI_ADD_UEVENT_VAR("DAHDI_TOOLS_ROOTDIR=%s", tools_rootdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s/%s", tools_rootdir, \
initdir); \
DAHDI_ADD_UEVENT_VAR("SPAN_NUM=%d", span->spanno); \
DAHDI_ADD_UEVENT_VAR("SPAN_NAME=%s", span->name); \
} while (0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
static int span_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct dahdi_span *span;
int i = 0;
int len = 0;
if (!dev)
return -ENODEV;
span = dev_to_span(dev);
if (!span)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
dev_name(dev), span->name);
SPAN_VAR_BLOCK;
envp[i] = NULL;
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, NULL, "%s", name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_device_create(class, NULL, devt, device, name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_device_create(class, devt, device, name)
#else
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(kenv, fmt, val); \
if (err) \
return err; \
} while (0)
static int span_uevent(struct device *dev, struct kobj_uevent_env *kenv)
{
struct dahdi_span *span;
if (!dev)
return -ENODEV;
span = dev_to_span(dev);
if (!span)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
dev_name(dev), span->name);
SPAN_VAR_BLOCK;
return 0;
}
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_simple_device_add(class, devt, device, name)
#endif
#define span_attr(field, format_string) \
static BUS_ATTR_READER(field##_show, dev, buf) \
{ \
struct dahdi_span *span; \
\
span = dev_to_span(dev); \
return sprintf(buf, format_string, span->field); \
}
span_attr(name, "%s\n");
span_attr(desc, "%s\n");
span_attr(alarms, "0x%x\n");
span_attr(lbo, "%d\n");
span_attr(syncsrc, "%d\n");
static BUS_ATTR_READER(spantype_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%s\n", dahdi_spantype2str(span->spantype));
}
static BUS_ATTR_READER(local_spanno_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%d\n", local_spanno(span));
}
static BUS_ATTR_READER(is_digital_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%d\n", dahdi_is_digital_span(span));
}
static BUS_ATTR_READER(is_sync_master_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%d\n", dahdi_is_sync_master(span));
}
static BUS_ATTR_READER(basechan_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
if (!span->channels)
return -ENODEV;
return sprintf(buf, "%d\n", span->chans[0]->channo);
}
static BUS_ATTR_READER(channels_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%d\n", span->channels);
}
static BUS_ATTR_READER(lineconfig_show, dev, buf)
{
struct dahdi_span *span;
int len = 0;
span = dev_to_span(dev);
len += lineconfig_str(span->lineconfig, buf, 20);
len += sprintf(buf + len, "\n");
return len;
}
static BUS_ATTR_READER(linecompat_show, dev, buf)
{
struct dahdi_span *span;
int bit;
int len = 0;
span = dev_to_span(dev);
for (bit = 4; bit <= 12; bit++) {
if (span->linecompat & (1 << bit)) {
const char *name = dahdi_lineconfig_bit_name(bit);
if (name)
len += sprintf(buf + len, "%s ", name);
}
}
/* chomp */
while (len > 0 && isspace(buf[len - 1]))
buf[--len] = '\0';
len += sprintf(buf + len, "\n");
return len;
}
static struct device_attribute span_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(desc),
__ATTR_RO(spantype),
__ATTR_RO(local_spanno),
__ATTR_RO(alarms),
__ATTR_RO(lbo),
__ATTR_RO(syncsrc),
__ATTR_RO(is_digital),
__ATTR_RO(is_sync_master),
__ATTR_RO(basechan),
__ATTR_RO(channels),
__ATTR_RO(lineconfig),
__ATTR_RO(linecompat),
__ATTR_NULL,
};
static ssize_t master_span_show(struct device_driver *driver, char *buf)
{
struct dahdi_span *s = get_master_span();
return snprintf(buf, PAGE_SIZE, "%d\n", (s) ? s->spanno : 0);
}
static ssize_t master_span_store(struct device_driver *driver, const char *buf,
size_t count)
{
int spanno;
if (sscanf(buf, "%d", &spanno) != 1) {
module_printk(KERN_ERR, "non-numeric input '%s'\n", buf);
return -EINVAL;
}
set_master_span(spanno);
return count;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
static struct driver_attribute dahdi_attrs[] = {
__ATTR(master_span, S_IRUGO | S_IWUSR, master_span_show,
master_span_store),
__ATTR_NULL,
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#define CLASS_DEV_DESTROY(class, devt) \
device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define CLASS_DEV_DESTROY(class, devt) \
class_device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
#define CLASS_DEV_DESTROY(class, devt) \
class_simple_device_remove(devt)
#else
static DRIVER_ATTR_RW(master_span);
static struct attribute *dahdi_attrs[] = {
&driver_attr_master_span.attr,
NULL,
};
ATTRIBUTE_GROUPS(dahdi);
#define CLASS_DEV_DESTROY(class, devt) \
class_simple_device_remove(class, devt)
#endif
static struct bus_type spans_bus_type = {
.name = "dahdi_spans",
.match = span_match,
.uevent = span_uevent,
.dev_attrs = span_dev_attrs,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
.drv_attrs = dahdi_attrs,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
static struct class *dahdi_class = NULL;
#else
.drv_groups = dahdi_groups,
static struct class_simple *dahdi_class = NULL;
#define class_create class_simple_create
#define class_destroy class_simple_destroy
#endif
};
static int span_probe(struct device *dev)
int dahdi_register_chardev(struct dahdi_chardev *dev)
{
struct dahdi_span *span;
static const char *DAHDI_STRING = "dahdi!";
char *udevname;
span = dev_to_span(dev);
span_dbg(DEVICES, span, "\n");
udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1,
GFP_KERNEL);
if (!udevname)
return -ENOMEM;
strcpy(udevname, DAHDI_STRING);
strcat(udevname, dev->name);
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
kfree(udevname);
return 0;
}
EXPORT_SYMBOL(dahdi_register_chardev);
static int span_remove(struct device *dev)
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
{
struct dahdi_span *span;
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
span = dev_to_span(dev);
span_dbg(DEVICES, span, "\n");
return 0;
}
static struct device_driver dahdi_driver = {
.name = "generic_lowlevel",
.bus = &spans_bus_type,
.probe = span_probe,
.remove = span_remove,
.owner = THIS_MODULE
};
static void span_uevent_send(struct dahdi_span *span, enum kobject_action act)
{
struct kobject *kobj;
kobj = &span->span_device->kobj;
span_dbg(DEVICES, span, "SYFS dev_name=%s action=%d\n",
dev_name(span->span_device), act);
kobject_uevent(kobj, act);
}
static void span_release(struct device *dev)
{
dahdi_dbg(DEVICES, "%s: %s\n", __func__, dev_name(dev));
}
EXPORT_SYMBOL(dahdi_unregister_chardev);
void span_sysfs_remove(struct dahdi_span *span)
{
struct device *span_device;
int x;
for (x = 0; x < span->channels; x++) {
struct dahdi_chan *chan = span->chans[x];
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
continue;
span_dbg(DEVICES, span, "\n");
span_device = span->span_device;
if (!span_device)
return;
for (x = 0; x < span->channels; x++)
chan_sysfs_remove(span->chans[x]);
if (!dev_get_drvdata(span_device))
return;
/* Grab an extra reference to the device since we'll still want it
* after we've unregistered it */
get_device(span_device);
span_uevent_send(span, KOBJ_OFFLINE);
sysfs_remove_link(&span_device->kobj, "ddev");
device_unregister(span->span_device);
dev_set_drvdata(span_device, NULL);
span_device->parent = NULL;
put_device(span_device);
memset(&span->span_device, 0, sizeof(span->span_device));
kfree(span->span_device);
span->span_device = NULL;
CLASS_DEV_DESTROY(dahdi_class,
MKDEV(DAHDI_MAJOR, chan->channo));
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
}
}
int span_sysfs_create(struct dahdi_span *span)
{
struct device *span_device;
int res = 0;
int x;
if (span->span_device) {
WARN_ON(1);
return -EEXIST;
}
span->span_device = kzalloc(sizeof(*span->span_device), GFP_KERNEL);
if (!span->span_device)
return -ENOMEM;
span_device = span->span_device;
span_dbg(DEVICES, span, "\n");
span_device->bus = &spans_bus_type;
span_device->parent = &span->parent->dev;
dev_set_name(span_device, "span-%d", span->spanno);
dev_set_drvdata(span_device, span);
span_device->release = span_release;
res = device_register(span_device);
if (res) {
span_err(span, "%s: device_register failed: %d\n", __func__,
res);
kfree(span->span_device);
span->span_device = NULL;
goto cleanup;
}
res = sysfs_create_link(&span_device->kobj, &span_device->parent->kobj,
"ddev");
if (res) {
span_err(span, "%s: sysfs_create_link failed: %d\n", __func__,
res);
kfree(span->span_device);
span->span_device = NULL;
goto cleanup;
}
for (x = 0; x < span->channels; x++) {
res = chan_sysfs_create(span->chans[x]);
if (res)
struct dahdi_chan *chan = span->chans[x];
char chan_name[32];
void *dummy;
if (chan->channo >= 250)
continue;
if (test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
continue;
snprintf(chan_name, sizeof(chan_name), "dahdi!%d",
chan->channo);
dummy = (void *)CLASS_DEV_CREATE(dahdi_class,
MKDEV(DAHDI_MAJOR, chan->channo),
NULL, chan_name);
if (IS_ERR(dummy)) {
res = PTR_ERR(dummy);
chan_err(chan, "Failed creating sysfs device: %d\n",
res);
goto cleanup;
}
set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
}
return 0;
@@ -403,432 +126,105 @@ cleanup:
return res;
}
#define MAKE_DAHDI_DEV(num, name) \
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name)
#define DEL_DAHDI_DEV(num) \
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num))
/* Only used to flag that the device exists: */
static struct {
unsigned int clean_dahdi_driver:1;
unsigned int clean_span_bus_type:1;
unsigned int clean_device_bus:1;
unsigned int clean_chardev:1;
} should_cleanup;
unsigned int ctl:1;
unsigned int timer:1;
unsigned int channel:1;
unsigned int pseudo:1;
} dummy_dev;
static inline struct dahdi_device *to_ddev(struct device *dev)
void dahdi_sysfs_exit(void)
{
return container_of(dev, struct dahdi_device, dev);
}
#define DEVICE_VAR_BLOCK \
do { \
DAHDI_ADD_UEVENT_VAR("DAHDI_TOOLS_ROOTDIR=%s", tools_rootdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s/%s", tools_rootdir, \
initdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_DEVICE_HWID=%s", \
ddev->hardware_id); \
DAHDI_ADD_UEVENT_VAR("DAHDI_DEVICE_LOCATION=%s", \
ddev->location); \
} while (0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
static int device_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct dahdi_device *ddev;
int i = 0;
int len = 0;
if (!dev)
return -ENODEV;
ddev = to_ddev(dev);
if (!ddev)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s\n", dev_name(dev));
DEVICE_VAR_BLOCK;
envp[i] = NULL;
return 0;
}
#else
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(kenv, fmt, val); \
if (err) \
return err; \
} while (0)
static int device_uevent(struct device *dev, struct kobj_uevent_env *kenv)
{
struct dahdi_device *ddev;
if (!dev)
return -ENODEV;
ddev = to_ddev(dev);
if (!ddev)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s\n", dev_name(dev));
DEVICE_VAR_BLOCK;
return 0;
}
#endif
static ssize_t
dahdi_device_manufacturer_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
return sprintf(buf, "%s\n", ddev->manufacturer);
}
static ssize_t
dahdi_device_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
return sprintf(buf, "%s\n", ddev->devicetype);
}
static ssize_t
dahdi_device_span_count_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
unsigned int count = 0;
struct list_head *pos;
list_for_each(pos, &ddev->spans)
++count;
return sprintf(buf, "%d\n", count);
}
static ssize_t
dahdi_device_hardware_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
return sprintf(buf, "%s\n",
(ddev->hardware_id) ? ddev->hardware_id : "");
}
static ssize_t
dahdi_device_location_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
return sprintf(buf, "%s\n",
(ddev->location) ? ddev->location : "");
}
static ssize_t
dahdi_device_auto_assign(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dahdi_device *ddev = to_ddev(dev);
dahdi_assign_device_spans(ddev);
return count;
}
static ssize_t
dahdi_device_assign_span(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
struct dahdi_span *span;
unsigned int local_span_number;
unsigned int desired_spanno;
unsigned int desired_basechanno;
struct dahdi_device *const ddev = to_ddev(dev);
ret = sscanf(buf, "%u:%u:%u", &local_span_number, &desired_spanno,
&desired_basechanno);
if (ret != 3) {
dev_notice(dev, "bad input (should be <num>:<num>:<num>)\n");
return -EINVAL;
if (dummy_dev.pseudo) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
DEL_DAHDI_DEV(DAHDI_PSEUDO);
dummy_dev.pseudo = 0;
}
if (desired_spanno && !desired_basechanno) {
dev_notice(dev, "Must set span number AND base chan number\n");
return -EINVAL;
if (dummy_dev.channel) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/channel:\n");
DEL_DAHDI_DEV(DAHDI_CHANNEL);
dummy_dev.channel = 0;
}
list_for_each_entry(span, &ddev->spans, device_node) {
if (local_span_number == local_spanno(span)) {
ret = dahdi_assign_span(span, desired_spanno,
desired_basechanno, 1);
return (ret) ? ret : count;
}
if (dummy_dev.timer) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/timer:\n");
DEL_DAHDI_DEV(DAHDI_TIMER);
dummy_dev.timer = 0;
}
dev_notice(dev, "no match for local span number %d\n",
local_span_number);
return -EINVAL;
}
static ssize_t
dahdi_device_unassign_span(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
int ret;
unsigned int local_span_number;
struct dahdi_span *span;
struct dahdi_device *const ddev = to_ddev(dev);
ret = sscanf(buf, "%u", &local_span_number);
if (ret != 1)
return -EINVAL;
ret = -ENODEV;
list_for_each_entry(span, &ddev->spans, device_node) {
if (local_span_number == local_spanno(span))
ret = dahdi_unassign_span(span);
if (dummy_dev.ctl) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/ctl:\n");
DEL_DAHDI_DEV(DAHDI_CTL);
dummy_dev.ctl = 0;
}
if (-ENODEV == ret) {
if (printk_ratelimit()) {
dev_info(dev, "'%d' is an invalid local span number.\n",
local_span_number);
}
return -EINVAL;
if (dahdi_class) {
dahdi_dbg(DEVICES, "Destroying DAHDI class:\n");
class_destroy(dahdi_class);
dahdi_class = NULL;
}
return (ret < 0) ? ret : count;
}
static ssize_t
dahdi_spantype_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
int count = 0;
ssize_t total = 0;
struct dahdi_span *span;
/* TODO: Make sure this doesn't overflow the page. */
list_for_each_entry(span, &ddev->spans, device_node) {
count = sprintf(buf, "%d:%s\n",
local_spanno(span), dahdi_spantype2str(span->spantype));
buf += count;
total += count;
}
return total;
}
static ssize_t
dahdi_spantype_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dahdi_device *const ddev = to_ddev(dev);
int ret;
struct dahdi_span *span;
unsigned int local_span_number;
char spantype_name[80];
enum spantypes spantype;
ret = sscanf(buf, "%u:%70s", &local_span_number, spantype_name);
if (ret != 2) {
dev_err(&ddev->dev, "Wrong input format: '%s'\n", buf);
return -EINVAL;
}
spantype = dahdi_str2spantype(spantype_name);
if (spantype == SPANTYPE_INVALID) {
dev_err(&ddev->dev, "Invalid spantype: '%s'\n", buf);
return -EINVAL;
}
list_for_each_entry(span, &ddev->spans, device_node) {
if (local_spanno(span) == local_span_number)
break;
}
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
module_printk(KERN_WARNING, "Span %s is already assigned.\n",
span->name);
return -EINVAL;
}
if (local_spanno(span) != local_span_number) {
module_printk(KERN_WARNING,
"%d is not a valid local span number "
"for this device.\n", local_span_number);
return -EINVAL;
}
if (!span->ops->set_spantype) {
module_printk(KERN_WARNING, "Span %s does not support "
"setting type.\n", span->name);
return -EINVAL;
}
ret = span->ops->set_spantype(span, spantype);
return (ret < 0) ? ret : count;
}
static struct device_attribute dahdi_device_attrs[] = {
__ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL),
__ATTR(type, S_IRUGO, dahdi_device_type_show, NULL),
__ATTR(span_count, S_IRUGO, dahdi_device_span_count_show, NULL),
__ATTR(hardware_id, S_IRUGO, dahdi_device_hardware_id_show, NULL),
__ATTR(location, S_IRUGO, dahdi_device_location_show, NULL),
__ATTR(auto_assign, S_IWUSR, NULL, dahdi_device_auto_assign),
__ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span),
__ATTR(unassign_span, S_IWUSR, NULL, dahdi_device_unassign_span),
__ATTR(spantype, S_IWUSR | S_IRUGO, dahdi_spantype_show,
dahdi_spantype_store),
__ATTR_NULL,
};
static struct bus_type dahdi_device_bus = {
.name = "dahdi_devices",
.uevent = device_uevent,
.dev_attrs = dahdi_device_attrs,
};
static void dahdi_sysfs_cleanup(void)
{
dahdi_dbg(DEVICES, "SYSFS\n");
if (should_cleanup.clean_dahdi_driver) {
dahdi_dbg(DEVICES, "Unregister driver\n");
driver_unregister(&dahdi_driver);
should_cleanup.clean_dahdi_driver = 0;
}
if (should_cleanup.clean_span_bus_type) {
dahdi_dbg(DEVICES, "Unregister span bus type\n");
bus_unregister(&spans_bus_type);
should_cleanup.clean_span_bus_type = 0;
}
dahdi_sysfs_chan_exit();
if (should_cleanup.clean_chardev) {
dahdi_dbg(DEVICES, "Unregister character device\n");
unregister_chrdev(DAHDI_MAJOR, "dahdi");
should_cleanup.clean_chardev = 0;
}
if (should_cleanup.clean_device_bus) {
dahdi_dbg(DEVICES, "Unregister DAHDI device bus\n");
bus_unregister(&dahdi_device_bus);
should_cleanup.clean_device_bus = 0;
}
}
static void dahdi_device_release(struct device *dev)
{
struct dahdi_device *ddev = container_of(dev, struct dahdi_device, dev);
kfree(ddev);
}
/**
* dahdi_sysfs_add_device - Add the dahdi_device into the sysfs hierarchy.
* @ddev: The device to add.
* @parent: The physical device that is implementing this device.
*
* By adding the dahdi_device to the sysfs hierarchy user space can control
* how spans are numbered.
*
*/
int dahdi_sysfs_add_device(struct dahdi_device *ddev, struct device *parent)
{
int ret;
struct device *const dev = &ddev->dev;
const char *dn;
dev->parent = parent;
dev->bus = &dahdi_device_bus;
dn = dev_name(dev);
if (!dn || !*dn) {
/* Invent default name based on parent */
if (!parent)
return -EINVAL;
dev_set_name(dev, "%s:%s", parent->bus->name, dev_name(parent));
}
ret = device_add(dev);
return ret;
}
void dahdi_sysfs_init_device(struct dahdi_device *ddev)
{
device_initialize(&ddev->dev);
ddev->dev.release = dahdi_device_release;
}
void dahdi_sysfs_unregister_device(struct dahdi_device *ddev)
{
device_del(&ddev->dev);
unregister_chrdev(DAHDI_MAJOR, "dahdi");
}
int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
{
int res = 0;
void *dev;
dahdi_dbg(DEVICES, "Registering DAHDI device bus\n");
/* Handle dahdi-tools paths (for udev environment) */
if (tools_rootdir && initdir) {
dahdi_err("Cannot use tools-rootdir and initdir parameters simultaneously\n");
return -EINVAL;
}
if (initdir)
pr_notice("dahdi: initdir is depracated -- prefer using \"tools_rootdir\" parameter\n");
else
initdir = "/usr/share/dahdi";
if (!tools_rootdir)
tools_rootdir = "";
res = bus_register(&dahdi_device_bus);
if (res)
return res;
should_cleanup.clean_device_bus = 1;
dahdi_dbg(DEVICES,
"Registering character device (major=%d)\n", DAHDI_MAJOR);
res = register_chrdev(DAHDI_MAJOR, "dahdi", dahdi_fops);
if (res) {
module_printk(KERN_ERR,
"Unable to register DAHDI character device "
"handler on %d\n", DAHDI_MAJOR);
module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
return res;
}
should_cleanup.clean_chardev = 1;
res = dahdi_sysfs_chan_init(dahdi_fops);
if (res)
goto cleanup;
res = bus_register(&spans_bus_type);
if (res) {
dahdi_err("%s: bus_register(%s) failed. Error number %d",
__func__, spans_bus_type.name, res);
goto cleanup;
}
should_cleanup.clean_span_bus_type = 1;
res = driver_register(&dahdi_driver);
if (res) {
dahdi_err("%s: driver_register(%s) failed. Error number %d",
__func__, dahdi_driver.name, res);
goto cleanup;
}
should_cleanup.clean_dahdi_driver = 1;
module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n",
DAHDI_MAJOR);
module_printk(KERN_INFO, "Version: %s\n", dahdi_version);
dahdi_class = class_create(THIS_MODULE, "dahdi");
if (!dahdi_class) {
res = -EEXIST;
goto cleanup;
}
dahdi_dbg(DEVICES, "Creating /dev/dahdi/timer:\n");
dev = MAKE_DAHDI_DEV(DAHDI_TIMER, "dahdi!timer");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.timer = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/channel:\n");
dev = MAKE_DAHDI_DEV(DAHDI_CHANNEL, "dahdi!channel");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.channel = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/pseudo:\n");
dev = MAKE_DAHDI_DEV(DAHDI_PSEUDO, "dahdi!pseudo");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.pseudo = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/ctl:\n");
dev = MAKE_DAHDI_DEV(DAHDI_CTL, "dahdi!ctl");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.ctl = 1;
return 0;
cleanup:
dahdi_sysfs_cleanup();
dahdi_sysfs_exit();
return res;
}
void dahdi_sysfs_exit(void)
{
dahdi_sysfs_cleanup();
}

View File

@@ -1,55 +0,0 @@
#ifndef DAHDI_SYSFS_H
#define DAHDI_SYSFS_H
#define DEVICE_ATTR_READER(name, dev, buf) \
ssize_t name(struct device *dev, \
struct device_attribute *attr, \
char *buf)
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \
ssize_t name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count)
#define BUS_ATTR_READER(name, dev, buf) \
ssize_t name(struct device *dev, \
struct device_attribute *attr, \
char *buf)
#define BUS_ATTR_WRITER(name, dev, buf, count) \
ssize_t name(struct device *dev, \
struct device_attribute *attr, \
const char *buf, size_t count)
#define DRIVER_ATTR_READER(name, drv, buf) \
ssize_t name(struct device_driver *drv, char * buf)
/* Device file creation macros */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, NULL, "%s", name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, name)
#else
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_device_create(class, NULL, devt, device, name)
#endif
/* Device file destruction macros */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
#define CLASS_DEV_DESTROY(class, devt) \
device_destroy(class, devt)
#else
#define CLASS_DEV_DESTROY(class, devt) \
class_device_destroy(class, devt)
#endif
/* Global */
int __init dahdi_sysfs_chan_init(const struct file_operations *fops);
void dahdi_sysfs_chan_exit(void);
/* Channel Handling */
int chan_sysfs_create(struct dahdi_chan *chan);
void chan_sysfs_remove(struct dahdi_chan *chan);
#endif /* DAHDI_SYSFS_H */

View File

@@ -6,7 +6,6 @@
*
* Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
* Copyright (C) 2011, Xorcom
* Copyright (C) 2011, Digium, Inc
*
* All rights reserved.
*
@@ -35,28 +34,4 @@ void span_sysfs_remove(struct dahdi_span *span);
int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops);
void dahdi_sysfs_exit(void);
void dahdi_sysfs_init_device(struct dahdi_device *ddev);
int dahdi_sysfs_add_device(struct dahdi_device *ddev, struct device *parent);
void dahdi_sysfs_unregister_device(struct dahdi_device *ddev);
int dahdi_assign_span(struct dahdi_span *span, unsigned int spanno,
unsigned int basechan, int prefmaster);
int dahdi_unassign_span(struct dahdi_span *span);
int dahdi_assign_device_spans(struct dahdi_device *ddev);
static inline int get_span(struct dahdi_span *span)
{
return try_module_get(span->ops->owner);
}
static inline void put_span(struct dahdi_span *span)
{
module_put(span->ops->owner);
}
static inline int local_spanno(struct dahdi_span *span)
{
return span->offset + 1;
}
#endif /* _DAHDI_H */

View File

@@ -10,7 +10,7 @@
* Converted to use HighResTimers on i386 by Jeffery Palmer <jeff@triggerinc.com>
*
* Copyright (C) 2002, Hermes Softlab
* Copyright (C) 2004-2012, Digium, Inc.
* Copyright (C) 2004-2009, Digium, Inc.
*
* All rights reserved.
*
@@ -53,7 +53,7 @@
#if defined(USE_HIGHRESTIMER)
#include <linux/hrtimer.h>
#else
#include <linux/timer.h>
#include <linux/time.h>
#endif
#include <dahdi/kernel.h>
@@ -75,7 +75,6 @@ static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time)
#endif
struct dahdi_dummy {
struct dahdi_device *ddev;
struct dahdi_span span;
struct dahdi_chan _chan;
struct dahdi_chan *chan;
@@ -206,44 +205,37 @@ static const struct dahdi_span_ops dummy_ops = {
static int dahdi_dummy_initialize(struct dahdi_dummy *ztd)
{
int res = 0;
/* DAHDI stuff */
ztd->ddev = dahdi_create_device();
if (!ztd->ddev)
return -ENOMEM;
dev_set_name(&ztd->ddev->dev, "dahdi_dummy");
ztd->chan = &ztd->_chan;
sprintf(ztd->span.name, "DAHDI_DUMMY/1");
snprintf(ztd->span.desc, sizeof(ztd->span.desc) - 1, "%s (source: " CLOCK_SRC ") %d", ztd->span.name, 1);
sprintf(ztd->chan->name, "DAHDI_DUMMY/%d/%d", 1, 0);
ztd->ddev->devicetype = "DAHDI Dummy Timing";
strlcpy(ztd->span.devicetype, "DAHDI Dummy Timing",
sizeof(ztd->span.devicetype));
ztd->chan->chanpos = 1;
ztd->span.chans = &ztd->chan;
ztd->span.channels = 0; /* no channels on our span */
ztd->span.deflaw = DAHDI_LAW_MULAW;
ztd->chan->pvt = ztd;
ztd->span.ops = &dummy_ops;
list_add_tail(&ztd->span.device_node, &ztd->ddev->spans);
res = dahdi_register_device(ztd->ddev, NULL);
return res;
if (dahdi_register(&ztd->span, 0)) {
return -1;
}
return 0;
}
int init_module(void)
{
int res;
ztd = kzalloc(sizeof(*ztd), GFP_KERNEL);
if (ztd == NULL) {
printk(KERN_ERR "dahdi_dummy: Unable to allocate memory\n");
return -ENOMEM;
}
res = dahdi_dummy_initialize(ztd);
if (res) {
printk(KERN_ERR
"dahdi_dummy: Unable to intialize DAHDI driver (%d)\n",
res);
if (dahdi_dummy_initialize(ztd)) {
printk(KERN_ERR "dahdi_dummy: Unable to intialize DAHDI driver\n");
kfree(ztd);
return res;
return -ENODEV;
}
#if defined(USE_HIGHRESTIMER)
@@ -281,8 +273,7 @@ void cleanup_module(void)
atomic_set(&shutdown, 1);
del_timer_sync(&timer);
#endif
dahdi_unregister_device(ztd->ddev);
dahdi_free_device(ztd->ddev);
dahdi_unregister(&ztd->span);
kfree(ztd);
if (debug)
printk(KERN_DEBUG "dahdi_dummy: cleanup() finished\n");

View File

@@ -3,7 +3,7 @@
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2012, Digium, Inc.
* Copyright (C) 2001-2010, Digium, Inc.
*
* All rights reserved.
*
@@ -88,8 +88,6 @@ static int txerrors;
static struct tasklet_struct dahdi_dynamic_tlet;
static void dahdi_dynamic_tasklet(unsigned long data);
#else
static struct tasklet_struct dahdi_dynamic_flush_tlet;
#endif
static DEFINE_MUTEX(dspan_mutex);
@@ -202,33 +200,27 @@ static void __dahdi_dynamic_run(void)
{
struct dahdi_dynamic *d;
struct dahdi_dynamic_driver *drv;
int y;
rcu_read_lock();
list_for_each_entry_rcu(d, &dspan_list, list) {
for (y = 0; y < d->span.channels; y++) {
struct dahdi_chan *const c = d->span.chans[y];
/* Echo cancel double buffered data */
dahdi_ec_chunk(c, c->readchunk, c->writechunk);
}
dahdi_receive(&d->span);
dahdi_transmit(&d->span);
/* Handle all transmissions now */
dahdi_dynamic_sendmessage(d);
}
#ifdef ENABLE_TASKLETS
/* If tasklets are not enabled, the above section will be called in
* interrupt context and the flushing of each driver will be called in a
* separate tasklet that only handles that. This is necessary since some
* of the dynamic spans need to call functions that require interrupts
* to be enabled but dahdi_transmit / ...sendmessage needs to be called
* each time the masterspan is processed which happens with interrupts
* disabled.
*
*/
tasklet_hi_schedule(&dahdi_dynamic_flush_tlet);
#else
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
#endif
rcu_read_unlock();
}
@@ -378,9 +370,6 @@ void dahdi_dynamic_receive(struct dahdi_span *span, unsigned char *msg, int msgl
if (unlikely(rxpos != rxcnt))
printk(KERN_NOTICE "Span %s: Expected seq no %d, but received %d instead\n", span->name, rxcnt, rxpos);
dahdi_ec_span(span);
dahdi_receive(span);
/* If this is our master span, then run everything */
if (master)
dahdi_dynamic_run();
@@ -400,18 +389,32 @@ static void dahdi_dynamic_release(struct kref *kref)
WARN_ON(test_bit(DAHDI_FLAGBIT_REGISTERED, &d->span.flags));
if (d->pvt) {
if (d->driver && d->driver->destroy) {
__module_get(d->driver->owner);
d->driver->destroy(d);
module_put(d->driver->owner);
} else {
WARN_ON(1);
}
}
kfree(d->msgbuf);
for (x = 0; x < d->span.channels; x++)
kfree(d->chans[x]);
dahdi_free_device(d->ddev);
kfree(d);
}
static inline int dynamic_put(struct dahdi_dynamic *d)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
kref_put(&d->kref, dahdi_dynamic_release);
return 1;
#else
return kref_put(&d->kref, dahdi_dynamic_release);
#endif
}
static inline void dynamic_get(struct dahdi_dynamic *d)
@@ -470,25 +473,7 @@ static int _destroy_dynamic(struct dahdi_dynamic_span *dds)
return -EBUSY;
}
if (d->pvt) {
if (d->driver && d->driver->destroy) {
if (!try_module_get(d->driver->owner)) {
/* The driver for this device is in the
* process of unloading. Leave this dynamic on
* the list so it's cleaned up when the driver
* unregisters. */
dynamic_put(d);
return -ENXIO;
}
d->driver->destroy(d);
module_put(d->driver->owner);
} else {
WARN_ON(1);
}
d->pvt = NULL;
}
dahdi_unregister_device(d->ddev);
dahdi_unregister(&d->span);
spin_lock_irqsave(&dspan_lock, flags);
list_del_rcu(&d->list);
@@ -597,8 +582,8 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
d = kzalloc(sizeof(*d), GFP_KERNEL);
if (!d)
return -ENOMEM;
kref_init(&d->kref);
d->ddev = dahdi_create_device();
for (x = 0; x < dds->numchans; x++) {
d->chans[x] = kzalloc(sizeof(*d->chans[x]), GFP_KERNEL);
@@ -623,17 +608,12 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
strlcpy(d->dname, dds->driver, sizeof(d->dname));
strlcpy(d->addr, dds->addr, sizeof(d->addr));
d->timing = dds->timing;
snprintf(d->span.name, sizeof(d->span.name), "DYN/%s/%s",
dds->driver, dds->addr);
snprintf(d->span.desc, sizeof(d->span.desc),
"Dynamic '%s' span at '%s'", dds->driver, dds->addr);
sprintf(d->span.name, "DYN/%s/%s", dds->driver, dds->addr);
sprintf(d->span.desc, "Dynamic '%s' span at '%s'",
dds->driver, dds->addr);
d->span.deflaw = DAHDI_LAW_MULAW;
d->span.flags |= DAHDI_FLAG_RBS;
d->span.chans = d->chans;
d->span.spantype = SPANTYPE_DIGITAL_DYNAMIC;
d->span.linecompat = DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF |
DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_CCS |
DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CRC4 | DAHDI_CONFIG_NOTOPEN;
d->span.ops = &dynamic_ops;
for (x = 0; x < d->span.channels; x++) {
sprintf(d->chans[x]->name, "DYN/%s/%s/%d",
@@ -681,12 +661,8 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
return res;
}
d->ddev->devicetype = d->span.name;
d->ddev->hardware_id = d->span.name;
dev_set_name(&d->ddev->dev, "dynamic:%s:%d", dds->driver, dtd->id++);
list_add_tail(&d->span.device_node, &d->ddev->spans);
/* Whee! We're created. Now register the span */
if (dahdi_register_device(d->ddev, d->dev)) {
if (dahdi_register(&d->span, 0)) {
printk(KERN_NOTICE "Unable to register span '%s'\n",
d->span.name);
dynamic_put(d);
@@ -727,20 +703,6 @@ static void dahdi_dynamic_tasklet(unsigned long data)
}
taskletpending = 0;
}
#else
static void dahdi_dynamic_flush_tasklet(unsigned long data)
{
struct dahdi_dynamic_driver *drv;
rcu_read_lock();
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
rcu_read_unlock();
}
#endif
static int dahdi_dynamic_ioctl(unsigned int cmd, unsigned long data)
@@ -803,17 +765,19 @@ void dahdi_dynamic_unregister_driver(struct dahdi_dynamic_driver *dri)
list_for_each_entry_safe(d, n, &dspan_list, list) {
if (d->driver == dri) {
if (d->pvt) {
if (d->driver && d->driver->destroy)
if (d->driver && d->driver->destroy) {
__module_get(d->driver->owner);
d->driver->destroy(d);
else
module_put(d->driver->owner);
} else {
WARN_ON(1);
}
}
dahdi_unregister_device(d->ddev);
dahdi_unregister(&d->span);
spin_lock_irqsave(&dspan_lock, flags);
list_del_rcu(&d->list);
spin_unlock_irqrestore(&dspan_lock, flags);
synchronize_rcu();
d->driver = NULL;
dynamic_put(d);
}
}
@@ -857,13 +821,10 @@ static void check_for_red_alarm(unsigned long ignored)
mod_timer(&alarmcheck, jiffies + 1 * HZ);
}
static const struct dahdi_dynamic_ops dahdi_dynamic_ops = {
.owner = THIS_MODULE,
.ioctl = dahdi_dynamic_ioctl,
};
static int dahdi_dynamic_init(void)
{
dahdi_set_dynamic_ioctl(dahdi_dynamic_ioctl);
/* Start process to check for RED ALARM */
init_timer(&alarmcheck);
alarmcheck.expires = 0;
@@ -873,31 +834,20 @@ static int dahdi_dynamic_init(void)
mod_timer(&alarmcheck, jiffies + 1 * HZ);
#ifdef ENABLE_TASKLETS
tasklet_init(&dahdi_dynamic_tlet, dahdi_dynamic_tasklet, 0);
#else
tasklet_init(&dahdi_dynamic_flush_tlet, dahdi_dynamic_flush_tasklet, 0);
#endif
dahdi_set_dynamic_ops(&dahdi_dynamic_ops);
printk(KERN_INFO "DAHDI Dynamic Span support LOADED\n");
return 0;
}
static void dahdi_dynamic_cleanup(void)
{
dahdi_set_dynamic_ops(NULL);
#ifdef ENABLE_TASKLETS
if (taskletpending) {
tasklet_disable(&dahdi_dynamic_tlet);
tasklet_kill(&dahdi_dynamic_tlet);
}
#else
tasklet_disable(&dahdi_dynamic_flush_tlet);
tasklet_kill(&dahdi_dynamic_flush_tlet);
#endif
del_timer_sync(&alarmcheck);
/* Must call again in case it was running before and rescheduled
* itself. */
dahdi_set_dynamic_ioctl(NULL);
del_timer(&alarmcheck);
printk(KERN_INFO "DAHDI Dynamic Span support unloaded\n");
}

View File

@@ -3,7 +3,7 @@
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2012, Digium, Inc.
* Copyright (C) 2001-2008, Digium, Inc.
*
* All rights reserved.
*
@@ -71,12 +71,14 @@ static struct dahdi_span *ztdeth_getspan(unsigned char *addr, unsigned short sub
if (z)
span = z->span;
spin_unlock_irqrestore(&zlock, flags);
if (!span || !test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags))
return NULL;
return span;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
#else
static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
#endif
{
struct dahdi_span *span;
struct ztdeth_header *zh;
@@ -85,7 +87,11 @@ static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
#else
zh = (struct ztdeth_header *)skb->nh.raw;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
span = ztdeth_getspan(eth_hdr(skb)->h_source, zh->subaddr);
#else
span = ztdeth_getspan(skb->mac.ethernet->h_source, zh->subaddr);
#endif
if (span) {
skb_pull(skb, sizeof(struct ztdeth_header));
#ifdef NEW_SKB_LINEARIZE
@@ -146,7 +152,7 @@ static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
spin_lock_irqsave(&zlock, flags);
z = dyn->pvt;
if (z && z->dev) {
if (z->dev) {
/* Copy fields to local variables to remove spinlock ASAP */
dev = z->dev;
memcpy(addr, z->addr, sizeof(z->addr));
@@ -185,16 +191,15 @@ static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
spin_unlock_irqrestore(&zlock, flags);
}
/**
* ztdeth_flush - Flush all pending transactions.
*
* This function is always called in softirq context.
*/
static int ztdeth_flush(void)
{
struct sk_buff *skb;
while ((skb = skb_dequeue(&skbs)))
/* Handle all transmissions now */
while ((skb = skb_dequeue(&skbs))) {
dev_queue_xmit(skb);
}
return 0;
}
@@ -279,12 +284,11 @@ static void ztdeth_destroy(struct dahdi_dynamic *dyn)
prev = cur;
cur = cur->next;
}
spin_unlock_irqrestore(&zlock, flags);
if (cur == z) { /* Successfully removed */
dyn->pvt = NULL;
printk(KERN_INFO "TDMoE: Removed interface for %s\n", z->span->name);
kfree(z);
}
spin_unlock_irqrestore(&zlock, flags);
}
static int ztdeth_create(struct dahdi_dynamic *dyn, const char *addr)
@@ -407,22 +411,20 @@ static struct notifier_block ztdeth_nblock = {
static int __init ztdeth_init(void)
{
skb_queue_head_init(&skbs);
dev_add_pack(&ztdeth_ptype);
register_netdevice_notifier(&ztdeth_nblock);
dahdi_dynamic_register_driver(&ztd_eth);
skb_queue_head_init(&skbs);
return 0;
}
static void __exit ztdeth_exit(void)
{
dahdi_dynamic_unregister_driver(&ztd_eth);
unregister_netdevice_notifier(&ztdeth_nblock);
dev_remove_pack(&ztdeth_ptype);
skb_queue_purge(&skbs);
unregister_netdevice_notifier(&ztdeth_nblock);
dahdi_dynamic_unregister_driver(&ztd_eth);
}
MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support");

View File

@@ -36,7 +36,6 @@
#include <linux/netdevice.h>
#include <linux/notifier.h>
#include <linux/crc32.h>
#include <linux/seq_file.h>
/**
* Undefine USE_PROC_FS, if you do not want the /proc/dahdi/dynamic-ethmf
@@ -225,8 +224,13 @@ static inline int ethmf_trx_spans_ready(unsigned int addr_hash, struct ztdeth *(
/**
* Ethernet receiving side processing function.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
static int ztdethmf_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
#else
static int ztdethmf_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt)
#endif
{
int num_spans = 0, span_index = 0;
unsigned char *data;
@@ -263,8 +267,13 @@ static int ztdethmf_rcv(struct sk_buff *skb, struct net_device *dev,
rcu_read_lock();
do {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
find_ethmf(eth_hdr(skb)->h_source,
htons(span_index), &z, &span);
#else
find_ethmf(skb->mac.ethernet->h_source,
htons(span_index), &z, &span);
#endif
if (unlikely(!z || !span)) {
/* The recv'd span does not belong to us */
/* ethmf_errors_inc(); */
@@ -387,6 +396,10 @@ static void ztdethmf_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
struct net_device *dev;
unsigned char addr[ETH_ALEN];
int spans_ready = 0, index = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
static DEFINE_SPINLOCK(lock);
unsigned long flags;
#endif
if (atomic_read(&shutdown))
return;
@@ -398,12 +411,24 @@ static void ztdethmf_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
return;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
if (!atomic_read(&z->ready)) {
spin_lock_irqsave(&lock, flags);
atomic_inc(&z->ready);
if (1 == atomic_read(&z->ready)) {
memcpy(z->msgbuf, msg, msglen);
z->msgbuf_len = msglen;
}
spin_unlock_irqrestore(&lock, flags);
}
#else
if (!atomic_read(&z->ready)) {
if (atomic_inc_return(&z->ready) == 1) {
memcpy(z->msgbuf, msg, msglen);
z->msgbuf_len = msglen;
}
}
#endif
spans_ready = ethmf_trx_spans_ready(z->addr_hash, &ready_spans);
if (spans_ready) {
@@ -697,69 +722,71 @@ static void timer_callback(unsigned long param)
#ifdef USE_PROC_FS
static struct proc_dir_entry *proc_entry;
static const char *ztdethmf_procname = "dahdi/dynamic-ethmf";
static int ztdethmf_proc_show(struct seq_file *sfile, void *not_used)
static int ztdethmf_proc_read(char *page, char **start, off_t off, int count,
int *eof, void *data)
{
struct ztdeth *z = NULL;
int i = 0;
int len = 0, i = 0;
unsigned int group = 0, c = 0;
rcu_read_lock();
seq_printf(sfile, "Errors: %d\n\n", atomic_read(&errcount));
len += sprintf(page + len, "Errors: %d\n\n", atomic_read(&errcount));
for (group = 0; group < ETHMF_MAX_GROUPS; ++group) {
if (atomic_read(&(ethmf_groups[group].spans))) {
seq_printf(sfile, "Group #%d (0x%x)\n", i++,
ethmf_groups[group].hash_addr);
seq_printf(sfile, "Spans: %d\n",
atomic_read(&(ethmf_groups[group].spans)));
len += sprintf(page + len, "Group #%d (0x%x)\n", i++, ethmf_groups[group].hash_addr);
len += sprintf(page + len, " Spans: %d\n",
atomic_read(&(ethmf_groups[group].spans)));
c = 1;
list_for_each_entry_rcu(z, &ethmf_list, list) {
if (z->addr_hash == ethmf_groups[group].hash_addr) {
if (c == 1) {
seq_printf(sfile,
len += sprintf(page + len,
" Device: %s (MAC: %02x:%02x:%02x:%02x:%02x:%02x)\n",
z->ethdev,
z->addr[0], z->addr[1], z->addr[2],
z->addr[3], z->addr[4], z->addr[5]);
}
seq_printf(sfile, " Span %d: subaddr=%u ready=%d delay=%d real_channels=%d no_front_padding=%d\n",
len += sprintf(page + len, " Span %d: subaddr=%u ready=%d delay=%d real_channels=%d no_front_padding=%d\n",
c++, ntohs(z->subaddr),
atomic_read(&z->ready), atomic_read(&z->delay),
z->real_channels, atomic_read(&z->no_front_padding));
}
}
seq_printf(sfile, " Device UPs: %u\n",
len += sprintf(page + len, " Device UPs: %u\n",
atomic_read(&(ethmf_groups[group].devupcount)));
seq_printf(sfile, " Device DOWNs: %u\n",
len += sprintf(page + len, " Device DOWNs: %u\n",
atomic_read(&(ethmf_groups[group].devdowncount)));
seq_printf(sfile, " Rx Frames: %u\n",
len += sprintf(page + len, " Rx Frames: %u\n",
atomic_read(&(ethmf_groups[group].rxframecount)));
seq_printf(sfile, " Tx Frames: %u\n",
len += sprintf(page + len, " Tx Frames: %u\n",
atomic_read(&(ethmf_groups[group].txframecount)));
seq_printf(sfile, " Rx Bytes: %u\n",
len += sprintf(page + len, " Rx Bytes: %u\n",
atomic_read(&(ethmf_groups[group].rxbytecount)));
seq_printf(sfile, " Tx Bytes: %u\n",
len += sprintf(page + len, " Tx Bytes: %u\n",
atomic_read(&(ethmf_groups[group].txbytecount)));
if (len <= off) {
off -= len;
len = 0;
}
if (len > off+count)
break;
}
}
rcu_read_unlock();
return 0;
}
static int ztdethmf_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ztdethmf_proc_show, NULL);
if (len <= off) {
off -= len;
len = 0;
}
*start = page + off;
len -= off;
if (len > count)
len = count;
return len;
}
static const struct file_operations ztdethmf_proc_fops = {
.open = ztdethmf_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
#endif
static int __init ztdethmf_init(void)
@@ -777,8 +804,8 @@ static int __init ztdethmf_init(void)
skb_queue_head_init(&skbs);
#ifdef USE_PROC_FS
proc_entry = proc_create_data(ztdethmf_procname, 0444, NULL,
&ztdethmf_proc_fops, NULL);
proc_entry = create_proc_read_entry(ztdethmf_procname, 0444, NULL,
ztdethmf_proc_read, NULL);
if (!proc_entry) {
printk(KERN_ALERT "create_proc_read_entry failed.\n");
}

View File

@@ -78,11 +78,10 @@ static LIST_HEAD(dynamic_local_list);
static void
dahdi_dynamic_local_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
{
struct dahdi_dynamic_local *d;
struct dahdi_dynamic_local *const d = dyn->pvt;
unsigned long flags;
spin_lock_irqsave(&local_lock, flags);
d = dyn->pvt;
if (d && d->peer && d->peer->span) {
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &d->peer->span->flags))
dahdi_dynamic_receive(d->peer->span, msg, msglen);
@@ -131,12 +130,11 @@ static int digit2int(char d)
static void dahdi_dynamic_local_destroy(struct dahdi_dynamic *dyn)
{
struct dahdi_dynamic_local *d;
struct dahdi_dynamic_local *d = dyn->pvt;
unsigned long flags;
struct dahdi_dynamic_local *cur;
spin_lock_irqsave(&local_lock, flags);
d = dyn->pvt;
list_for_each_entry(cur, &dynamic_local_list, node) {
if (cur->peer == d)
cur->peer = NULL;

View File

@@ -7,7 +7,7 @@
* This "echo can" will completely hose your audio.
* Don't use it unless you're absolutely sure you know what you're doing.
*
* Copyright (C) 2007-2012, Digium, Inc.
* Copyright (C) 2007-2008, Digium, Inc.
*
* All rights reserved.
*
@@ -38,6 +38,9 @@
static int debug;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);

View File

@@ -5,7 +5,7 @@
*
* Based upon mec2.h
*
* Copyright (C) 2002-2012, Digium, Inc.
* Copyright (C) 2002, Digium, Inc.
*
* Additional background on the techniques used in this code can be found in:
*
@@ -44,6 +44,9 @@
static int debug;
static int aggressive;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
/* Uncomment to provide summary statistics for overall echo can performance every 4000 samples */
/* #define MEC2_STATS 4000 */

View File

@@ -5,7 +5,7 @@
*
* Based upon kb1ec.h and mec2.h
*
* Copyright (C) 2002-2012, Digium, Inc.
* Copyright (C) 2002, Digium, Inc.
*
* Additional background on the techniques used in this code can be found in:
*
@@ -44,6 +44,9 @@
static int debug;
static int aggressive;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk("%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
#define ABS(a) abs(a!=-32768?a:-32767)
#define RESTORE_COEFFS {\

View File

@@ -36,6 +36,8 @@
#include <dahdi/kernel.h>
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
static int echo_can_create(struct dahdi_chan *chan, struct dahdi_echocanparams *ecp,
struct dahdi_echocanparam *p, struct dahdi_echocan_state **ec);
static void echo_can_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);

View File

@@ -48,6 +48,9 @@
static int debug;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
#include "arith.h"
#ifndef NULL

View File

@@ -47,6 +47,9 @@
static int debug;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
#include "fir.h"
#ifndef NULL

View File

@@ -3,7 +3,7 @@
#
# Makefile for firmware downloading/installation
#
# Copyright (C) 2007-2013, Digium, Inc.
# Copyright (C) 2007-2010, Digium, Inc.
#
# Joshua Colp <jcolp@digium.com>
#
@@ -22,28 +22,16 @@
.PHONY: dist-clean clean all uninstall have_download install object-build hotplug-install hotplug-dirs hotplug-uninstall make_firmware_object firmware-loaders
OCT6114_032_VERSION:=1.05.01
OCT6114_064_VERSION:=1.05.01
OCT6114_128_VERSION:=1.05.01
OCT6114_256_VERSION:=1.05.01
TC400M_VERSION:=MR6.12
VPMADT032_VERSION:=1.25.0
HX8_VERSION:=2.06
VPMOCT032_VERSION:=1.12.0
WCT820_VERSION:=1.76
TE133_VERSION:=6f0017
TE134_VERSION:=6f0017
TE435_VERSION:=e0017
A8A_VERSION:=1d0017
A8B_VERSION:=1d0017
A4A_VERSION:=a0017
A4B_VERSION:=b0017
VPMOCT032_VERSION:=1.8.0
FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
ALL_FIRMWARE=FIRMWARE-OCT6114-032 FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-OCT6114-256
ALL_FIRMWARE+=FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032 FIRMWARE-TE820 FIRMWARE-TE133 FIRMWARE-TE134
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032
# Firmware files should use the naming convention: dahdi-fw-<base name>-<sub name>-<version> or dahdi-fw-<base name>-<version>
# First example: dahdi-fw-oct6114-064-1.05.01
@@ -52,32 +40,19 @@ ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
# This means this is version MR5.6 of the tc400m firmware
# Build a list of firmware package filenames we need
FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-032=dahdi-fw-oct6114-032-$(OCT6114_032_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz)
FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256-$(OCT6114_256_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TC400M=dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-HX8=dahdi-fw-hx8-$(HX8_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032-$(VPMOCT032_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE820=dahdi-fw-te820-$(WCT820_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE133=dahdi-fw-te133-$(TE133_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE134=dahdi-fw-te134-$(TE134_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE435=dahdi-fw-te435-$(TE435_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8A=dahdi-fw-a8b-$(A8B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8B=dahdi-fw-a8a-$(A8A_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4A=dahdi-fw-a4b-$(A4B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4B=dahdi-fw-a4a-$(A4A_VERSION).tar.gz)
FWLOADERS:=dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz
# Build a list of object files if hotplug will not be used
OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-032=dahdi-fw-oct6114-032.o)
OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-TC400M=dahdi-fw-tc400m.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-HX8=dahdi-fw-hx8.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032.o)
# Force usage of wget, for now
DOWNLOAD=wget
@@ -126,17 +101,6 @@ $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware:
# Install all downloaded firmware images for hotplug usage
hotplug-install: $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware $(FIRMWARE)
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-032-$(OCT6114_032_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-032-$(OCT6114_032_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-oct6114-032.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-oct6114-032.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-032-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-032-$(OCT6114_032_VERSION)
@install -m 644 dahdi-fw-oct6114-032.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-032-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-032-$(OCT6114_032_VERSION)
else
@echo "Firmware dahdi-fw-oct6114-032.bin is already installed with required version $(OCT6114_032_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-oct6114-064.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/usr/lib/hotplug/firmware
@@ -159,17 +123,6 @@ ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-12
else
@echo "Firmware dahdi-fw-oct6114-128.bin is already installed with required version $(OCT6114_128_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-oct6114-256.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-oct6114-256.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION)
@install -m 644 dahdi-fw-oct6114-256.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION)
else
@echo "Firmware dahdi-fw-oct6114-256.bin is already installed with required version $(OCT6114_256_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-tc400m.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/usr/lib/hotplug/firmware
@@ -203,95 +156,6 @@ ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-
else
@echo "Firmware dahdi-fw-vpmoct032.bin is already installed with required version $(VPMOCT032_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-$(WCT820_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-te820-$(WCT820_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-te820.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-te820.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-$(WCT820_VERSION)
@install -m 644 dahdi-fw-te820.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-te820-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-te820-$(WCT820_VERSION)
else
@echo "Firmware dahdi-fw-te820.bin is already installed with required version $(WCT820_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te133-$(TE133_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-te133-$(TE133_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-te133.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-te133.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te133-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te133-$(TE133_VERSION)
@install -m 644 dahdi-fw-te133.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-te133-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-te133-$(TE133_VERSION)
else
@echo "Firmware dahdi-fw-te133.bin is already installed with required version $(TE133_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te134-$(TE134_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-te134-$(TE134_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-te134.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-te134.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te134-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te134-$(TE134_VERSION)
@install -m 644 dahdi-fw-te134.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-te134-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-te134-$(TE134_VERSION)
else
@echo "Firmware dahdi-fw-te134.bin is already installed with required version $(TE134_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te435-$(TE435_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-te435-$(TE435_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-te435.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-te435.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te435-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te435-$(TE435_VERSION)
@install -m 644 dahdi-fw-te435.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-te435-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-te435-$(TE435_VERSION)
else
@echo "Firmware dahdi-fw-te435.bin is already installed with required version $(TE435_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8a-$(A8A_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-a8a-$(A8A_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-a8a.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-a8a.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8a-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8a-$(A8A_VERSION)
@install -m 644 dahdi-fw-a8a.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-a8a-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-a8a-$(A8A_VERSION)
else
@echo "Firmware dahdi-fw-a8a.bin is already installed with required version $(A8A_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8b-$(A8B_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-a8b-$(A8B_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-a8b.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-a8b.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8b-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a8b-$(A8B_VERSION)
@install -m 644 dahdi-fw-a8b.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-a8b-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-a8b-$(A8B_VERSION)
else
@echo "Firmware dahdi-fw-a8b.bin is already installed with required version $(A8B_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4a-$(A4A_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-a4a-$(A4A_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-a4a.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-a4a.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4a-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4a-$(A4A_VERSION)
@install -m 644 dahdi-fw-a4a.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-a4a-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-a4a-$(A4A_VERSION)
else
@echo "Firmware dahdi-fw-a4a.bin is already installed with required version $(A4A_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4b-$(A4B_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-a4b-$(A4B_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-a4b.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-a4b.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4b-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-a4b-$(A4B_VERSION)
@install -m 645 dahdi-fw-a4b.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-a4b-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-a4b-$(A4B_VERSION)
else
@echo "Firmware dahdi-fw-a4b.bin is already installed with required version $(A4B_VERSION)"
endif
# Uninstall any installed dahdi firmware images from hotplug firmware directories
hotplug-uninstall:
@@ -310,11 +174,6 @@ make_firmware_object: make_firmware_object.in ../dahdi-base.o
sed -e s/BFDNAME/$${BFDNAME}/ -e s/BFDARCH/$${BFDARCH}/ $< > $@
@chmod +x $@
# Build object file of an oct6114 032 firmware image for linking
dahdi-fw-oct6114-032.o: dahdi-fw-oct6114-032-$(OCT6114_032_VERSION).tar.gz dahdi-fw-oct6114-032.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-oct6114-032.bin
./make_firmware_object dahdi-fw-oct6114-032.bin $@
# Build object file of an oct6114 064 firmware image for linking
dahdi-fw-oct6114-064.o: dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz dahdi-fw-oct6114-064.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-oct6114-064.bin
@@ -325,17 +184,7 @@ dahdi-fw-oct6114-128.o: dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz dahdi
@echo Making firmware object file for dahdi-fw-oct6114-128.bin
./make_firmware_object dahdi-fw-oct6114-128.bin $@
# Build object file of an oct6114 256 firmware image for linking
dahdi-fw-oct6114-256.o: dahdi-fw-oct6114-256-$(OCT6114_256_VERSION).tar.gz dahdi-fw-oct6114-256.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-oct6114-256.bin
./make_firmware_object dahdi-fw-oct6114-256.bin $@
# Build object file of a TC400M firmware image for linking
dahdi-fw-tc400m.o: dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz dahdi-fw-tc400m.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-tc400m.bin
./make_firmware_object dahdi-fw-tc400m.bin $@
# Build object file of a VPMOCT032 firmware image for linking
dahdi-fw-vpmoct032.o: dahdi-fw-vpmoct032-$(VPMOCT032_VERSION).tar.gz dahdi-fw-vpmoct032.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-vpmoct032.bin
./make_firmware_object dahdi-fw-vpmoct032.bin $@

View File

@@ -1,7 +1,7 @@
/*
* DAHDI Telephony Interface to Digium High-Performance Echo Canceller
*
* Copyright (C) 2006-2012 Digium, Inc.
* Copyright (C) 2006-2008 Digium, Inc.
*
* All rights reserved.
*
@@ -31,6 +31,9 @@
static int debug;
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#define debug_printk(level, fmt, args...) if (debug >= level) printk(KERN_DEBUG "%s (%s): " fmt, THIS_MODULE->name, __FUNCTION__, ## args)
#include "hpec_user.h"
#include "hpec.h"
@@ -72,9 +75,18 @@ static int __attribute__((regparm(0), format(printf, 1, 2))) logger(const char *
int res;
va_list args;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
va_start(args, format);
res = vprintk(format, args);
va_end(args);
#else
char buf[256];
va_start(args, format);
res = vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
printk(KERN_INFO "%s" buf);
#endif
return res;
}

View File

@@ -1,32 +0,0 @@
#
# Produces the oct612x library
#
octapi_files = octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_events.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o \
apilib/bt/octapi_bt0.o \
apilib/largmath/octapi_largmath.o \
apilib/llman/octapi_llman.o \
oct612x-user.o
# TODO: ccflags was added in 2.6.24 in commit f77bf01425b11947eeb3b5b54. This
# should be changed to a conditional compilation based on the Kernel Version.
# ccflags-y := -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
EXTRA_CFLAGS = -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OCT612X) := oct612x.o
oct612x-objs := $(octapi_files)

View File

@@ -1,30 +1,38 @@
#
# Produces the oct612x library
#
octapi_files = octdeviceapi/oct6100api/oct6100_api/oct6100_adpcm_chan.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_channel.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_open.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_chip_stats.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_conf_bridge.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_events.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_interrupts.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_memory.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_miscellaneous.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_mixer.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_phasing_tsst.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_playout_buf.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_remote_debug.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tlv.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tone_detection.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsi_cnct.o \
octdeviceapi/oct6100api/oct6100_api/oct6100_tsst.o \
apilib/bt/octapi_bt0.o \
apilib/largmath/octapi_largmath.o \
apilib/llman/octapi_llman.o
CFLAGS=-V3.4 -ffunction-sections -I/lib/modules/$(shell uname -r)/build/include -Iinclude -Ioctdeviceapi -Ioctdeviceapi/oct6100api -DGFP_ATOMIC=0 -Dkmalloc=calloc -Dkfree=free
LDFLAGS=-V3.4 -Wl,-Map -Wl,test.map -Wl,--gc-sections
# TODO: ccflags was added in 2.6.24 in commit f77bf01425b11947eeb3b5b54. This
# should be changed to a conditional compilation based on the Kernel Version.
# ccflags-y := -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
EXTRA_CFLAGS = -I$(src)/.. -Wno-undef -I$(src)/include -I$(src)/octdeviceapi -I$(src)/octdeviceapi/oct6100api
lib-y := $(octapi_files)
APIDIR=octdeviceapi/oct6100api/oct6100_api
OCTASIC_OBJS=$(APIDIR)/oct6100_adpcm_chan.o \
$(APIDIR)/oct6100_channel.o \
$(APIDIR)/oct6100_chip_open.o \
$(APIDIR)/oct6100_chip_stats.o \
$(APIDIR)/oct6100_conf_bridge.o \
$(APIDIR)/oct6100_debug.o \
$(APIDIR)/oct6100_events.o \
$(APIDIR)/oct6100_interrupts.o \
$(APIDIR)/oct6100_memory.o \
$(APIDIR)/oct6100_miscellaneous.o \
$(APIDIR)/oct6100_mixer.o \
$(APIDIR)/oct6100_phasing_tsst.o \
$(APIDIR)/oct6100_playout_buf.o \
$(APIDIR)/oct6100_remote_debug.o \
$(APIDIR)/oct6100_tlv.o \
$(APIDIR)/oct6100_tone_detection.o \
$(APIDIR)/oct6100_tsi_cnct.o \
$(APIDIR)/oct6100_tsst.o \
$(APIDIR)/oct6100_user.o \
apilib/bt/octapi_bt0.o \
apilib/largmath/octapi_largmath.o \
apilib/llman/octapi_llman.o
all: test
test.o: test.c
test: test.o $(OCTASIC_OBJS)
clean:
rm -rf test test.o
rm -rf $(OCTASIC_OBJS)

View File

@@ -397,7 +397,7 @@ $Octasic_Revision: 171 $
/* Max defines.*/
#ifndef cOCT6100_MAX_ECHO_CHANNELS
#define cOCT6100_MAX_ECHO_CHANNELS 256
#define cOCT6100_MAX_ECHO_CHANNELS 128
#endif
#define cOCT6100_MAX_TSI_CNCTS 1530
#define cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ( 3328 + 6 )

View File

@@ -1,200 +0,0 @@
/*
* Octasic OCT6100 Interface
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <dahdi/kernel.h>
#include "oct612x.h"
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
{
/* Why couldn't they just take a timeval like everyone else? */
struct timeval tv;
unsigned long long total_usecs;
unsigned int mask = ~0;
do_gettimeofday(&tv);
total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
(((unsigned long long)(tv.tv_usec)));
f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern,
UINT32 f_ulLength)
{
memset(f_pAddress, f_ulPattern, f_ulLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource,
UINT32 f_ulLength)
{
memcpy(f_pDestination, f_pSource, f_ulLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserCreateSerializeObject(
tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
{
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDestroySerializeObject(
tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
{
#ifdef OCTASIC_DEBUG
pr_debug("I should never be called! (destroy serialize object)\n");
#endif
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserSeizeSerializeObject(
tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserReleaseSerializeObject(
tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
{
struct oct612x_context *context = f_pWriteParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write(context, f_pWriteParams->ulWriteAddress,
f_pWriteParams->usWriteData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
{
struct oct612x_context *context = f_pSmearParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write_smear) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write_smear(context, f_pSmearParams->ulWriteAddress,
f_pSmearParams->usWriteData,
f_pSmearParams->ulWriteLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteBurstApi(
tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
{
struct oct612x_context *context = f_pBurstParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->write_burst) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->write_burst(context, f_pBurstParams->ulWriteAddress,
f_pBurstParams->pusWriteData,
f_pBurstParams->ulWriteLength);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
{
struct oct612x_context *context = f_pReadParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->read) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->read(context, f_pReadParams->ulReadAddress,
f_pReadParams->pusReadData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
{
struct oct612x_context *context = f_pBurstParams->pProcessContext;
#ifdef OCTASIC_DEBUG
if (!context || !context->ops || !context->ops->read_burst) {
pr_debug("Invalid call to %s\n", __func__);
return cOCT6100_ERR_BASE;
}
#endif
context->ops->read_burst(context, f_pBurstParams->ulReadAddress,
f_pBurstParams->pusReadData,
f_pBurstParams->ulReadLength);
return cOCT6100_ERR_OK;
}
EXPORT_SYMBOL(Oct6100ChipOpen);
EXPORT_SYMBOL(Oct6100ChipClose);
EXPORT_SYMBOL(Oct6100ChipCloseDef);
EXPORT_SYMBOL(Oct6100GetInstanceSize);
EXPORT_SYMBOL(Oct6100GetInstanceSizeDef);
EXPORT_SYMBOL(Oct6100ChipOpenDef);
EXPORT_SYMBOL(Oct6100ChannelModify);
EXPORT_SYMBOL(Oct6100ToneDetectionEnableDef);
EXPORT_SYMBOL(Oct6100InterruptServiceRoutine);
EXPORT_SYMBOL(Oct6100InterruptServiceRoutineDef);
EXPORT_SYMBOL(Oct6100ApiGetCapacityPins);
EXPORT_SYMBOL(Oct6100ToneDetectionEnable);
EXPORT_SYMBOL(Oct6100EventGetToneDef);
EXPORT_SYMBOL(Oct6100EventGetTone);
EXPORT_SYMBOL(Oct6100ApiGetCapacityPinsDef);
EXPORT_SYMBOL(Oct6100ChannelOpen);
EXPORT_SYMBOL(Oct6100ChannelOpenDef);
EXPORT_SYMBOL(Oct6100ChannelModifyDef);
static int __init oct612x_module_init(void)
{
/* This registration with dahdi.ko will fail since the span is not
* defined, but it will make sure that this module is a dependency of
* dahdi.ko, so that when it is being unloded, this module will be
* unloaded as well. */
dahdi_register_device(NULL, NULL);
return 0;
}
module_init(oct612x_module_init);
static void __exit oct612x_module_cleanup(void)
{
/* Nothing to do */;
}
module_exit(oct612x_module_cleanup);
MODULE_AUTHOR("Digium Incorporated <support@digium.com>");
MODULE_DESCRIPTION("Octasic OCT6100 Hardware Echocan Library");
MODULE_LICENSE("GPL v2");

View File

@@ -1,49 +0,0 @@
/*
* Octasic OCT6100 Interface
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#ifndef __OCT612X_H__
#define __OCT612X_H__
#include <oct6100api/oct6100_api.h>
struct oct612x_context;
/**
* struct oct612x_ops - Callbacks used by oct612x library to talk to part.
*
*/
struct oct612x_ops {
int (*write)(struct oct612x_context *context, u32 address, u16 value);
int (*read)(struct oct612x_context *context, u32 address, u16 *value);
int (*write_smear)(struct oct612x_context *context, u32 address,
u16 value, size_t count);
int (*write_burst)(struct oct612x_context *context, u32 address,
const u16 *value, size_t count);
int (*read_burst)(struct oct612x_context *context, u32 address,
u16 *value, size_t count);
};
struct oct612x_context {
const struct oct612x_ops *ops;
struct device *dev;
};
#endif /* __OCT612X_H__ */

View File

@@ -146,7 +146,6 @@ struct encdec
struct pciradio {
struct pci_dev *dev;
struct dahdi_device *ddev;
struct dahdi_span span;
unsigned char ios;
int usecount;
@@ -1489,7 +1488,7 @@ static int pciradio_initialize(struct pciradio *rad)
rad->span.flags = DAHDI_FLAG_RBS;
rad->span.ops = &pciradio_span_ops;
if (dahdi_register_device(rad->ddev, &rad->dev->dev)) {
if (dahdi_register(&rad->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
}
@@ -1778,7 +1777,7 @@ static int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
release_region(rad->ioaddr, 0xff);
pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)rad->writechunk, rad->writedma);
pci_set_drvdata(pdev, NULL);
dahdi_free_device(rad->ddev);
dahdi_unregister(&rad->span);
kfree(rad);
return -EIO;
@@ -1811,7 +1810,7 @@ static int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
static void pciradio_release(struct pciradio *rad)
{
dahdi_unregister_device(rad->ddev);
dahdi_unregister(&rad->span);
if (rad->freeregion)
release_region(rad->ioaddr, 0xff);
kfree(rad);

View File

@@ -97,7 +97,6 @@ struct tor2 {
unsigned long xilinx8_region; /* 8 bit Region allocated to Xilinx */
unsigned long xilinx8_len; /* Length of 8 bit Xilinx region */
__iomem volatile unsigned char *mem8; /* Virtual representation of 8 bit Xilinx memory area */
struct dahdi_device *ddev;
struct tor2_span tspans[SPANS_PER_CARD]; /* Span data */
struct dahdi_chan **chans[SPANS_PER_CARD]; /* Pointers to card channels */
struct tor2_chan tchans[32 * SPANS_PER_CARD]; /* Channel user data */
@@ -286,16 +285,20 @@ static void init_spans(struct tor2 *tor)
snprintf(s->desc, sizeof(s->desc) - 1,
"Tormenta 2 (PCI) Quad %s Card %d Span %d",
(tor->cardtype == TYPE_T1) ? "T1" : "E1", tor->num, x + 1);
s->manufacturer = "Digium";
strlcpy(s->devicetype, tor->type, sizeof(s->devicetype));
snprintf(s->location, sizeof(s->location) - 1,
"PCI Bus %02d Slot %02d", tor->pci->bus->number, PCI_SLOT(tor->pci->devfn) + 1);
if (tor->cardtype == TYPE_T1) {
s->channels = 24;
s->deflaw = DAHDI_LAW_MULAW;
s->linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
s->spantype = SPANTYPE_DIGITAL_T1;
s->spantype = "T1";
} else {
s->channels = 31;
s->deflaw = DAHDI_LAW_ALAW;
s->linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
s->spantype = SPANTYPE_DIGITAL_E1;
s->spantype = "E1";
}
s->chans = tor->chans[x];
s->flags = DAHDI_FLAG_RBS;
@@ -319,31 +322,19 @@ static void init_spans(struct tor2 *tor)
static int __devinit tor2_launch(struct tor2 *tor)
{
int res;
struct dahdi_span *s;
int i;
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &tor->tspans[0].dahdi_span.flags))
return 0;
tor->ddev = dahdi_create_device();
tor->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
tor->pci->bus->number,
PCI_SLOT(tor->pci->devfn) + 1);
if (!tor->ddev->location)
return -ENOMEM;
printk(KERN_INFO "Tor2: Launching card: %d\n", tor->order);
for (i = 0; i < SPANS_PER_CARD; ++i) {
s = &tor->tspans[i].dahdi_span;
list_add_tail(&s->device_node, &tor->ddev->spans);
}
res = dahdi_register_device(tor->ddev, &tor->pci->dev);
if (res) {
dev_err(&tor->pci->dev, "Unable to register with DAHDI.\n");
return res;
if (dahdi_register(s, 0)) {
printk(KERN_ERR "Unable to register span %s\n", s->name);
goto error_exit;
}
}
writew(PLX_INTENA, &tor->plx[INTCSR]); /* enable PLX interrupt */
@@ -351,6 +342,14 @@ static int __devinit tor2_launch(struct tor2 *tor)
tasklet_init(&tor->tor2_tlet, tor2_tasklet, (unsigned long)tor);
#endif
return 0;
error_exit:
for (i = 0; i < SPANS_PER_CARD; ++i) {
s = &tor->tspans[i].dahdi_span;
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
dahdi_unregister(s);
}
return -1;
}
static void free_tor(struct tor2 *tor)
@@ -366,8 +365,6 @@ static void free_tor(struct tor2 *tor)
if (tor->chans[x])
kfree(tor->chans[x]);
}
kfree(tor->ddev->location);
dahdi_free_device(tor->ddev);
kfree(tor);
}
@@ -634,6 +631,7 @@ static struct pci_driver tor2_driver;
static void __devexit tor2_remove(struct pci_dev *pdev)
{
struct tor2 *tor;
int i;
tor = pci_get_drvdata(pdev);
if (!tor)
@@ -643,7 +641,11 @@ static void __devexit tor2_remove(struct pci_dev *pdev)
writeb(0, &tor->mem8[LEDREG]);
writew(0, &tor->plx[INTCSR]);
free_irq(tor->irq, tor);
dahdi_unregister_device(tor->ddev);
for (i = 0; i < SPANS_PER_CARD; ++i) {
struct dahdi_span *s = &tor->tspans[i].dahdi_span;
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
dahdi_unregister(s);
}
release_mem_region(tor->plx_region, tor->plx_len);
release_mem_region(tor->xilinx32_region, tor->xilinx32_len);
release_mem_region(tor->xilinx8_region, tor->xilinx8_len);

View File

@@ -126,8 +126,8 @@ static int vpmadt032_getreg_full_return(struct vpmadt032 *vpm, int pagechange,
unsigned long ret;
BUG_ON(!cmd);
/* We'll wait for 2s */
ret = wait_for_completion_timeout(&cmd->complete, HZ*2);
/* We'll wait for 200ms */
ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
if (unlikely(!ret)) {
spin_lock_irqsave(&vpm->list_lock, flags);
list_del(&cmd->node);

View File

@@ -36,7 +36,6 @@
#ifndef _GPAKCUST_H /* prevent multiple inclusion */
#define _GPAKCUST_H
#include <linux/module.h>
#include <linux/device.h>
#include <linux/completion.h>
#include <linux/workqueue.h>

View File

@@ -2,17 +2,4 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += dahdi_voicebus.o
dahdi_voicebus-objs := voicebus.o GpakCust.o GpakApi.o voicebus_net.o vpmoct.o
FIRM_DIR := ../firmware
ifneq ($(HOTPLUG_FIRMWARE),yes)
dahdi_voicebus-objs += $(FIRM_DIR)/dahdi-fw-vpmoct032.o
$(warning WARNING: You are compiling firmware into voicebus.ko which is not available under the terms of the GPL. It may be a violation of the GPL to distribute the resulting image since it combines both GPL and non-GPL work. You should consult a lawyer of your own before distributing such an image.)
else
EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
endif
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
$(obj)/$(FIRM_DIR)/dahdi-fw-vpmoct032.o: $(obj)/voicebus.o
$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-vpmoct032.o
EXTRA_CFLAGS := -I$(src)/.. -Wno-undef

View File

@@ -0,0 +1,6 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
endif

View File

@@ -1683,7 +1683,6 @@ vb_isr(int irq, void *dev_id)
#endif
{
struct voicebus *vb = dev_id;
unsigned long flags;
u32 int_status;
int_status = __vb_getctl(vb, SR_CSR5);
@@ -1694,8 +1693,6 @@ vb_isr(int irq, void *dev_id)
if (!int_status)
return IRQ_NONE;
local_irq_save(flags);
if (unlikely((int_status &
(TX_UNAVAILABLE_INTERRUPT|RX_UNAVAILABLE_INTERRUPT)) &&
!test_bit(VOICEBUS_STOP, &vb->flags) &&
@@ -1736,7 +1733,6 @@ vb_isr(int irq, void *dev_id)
/* Clear the interrupt(s) */
__vb_setctl(vb, SR_CSR5, int_status);
}
local_irq_restore(flags);
return IRQ_HANDLED;
}
@@ -1885,7 +1881,7 @@ __voicebus_init(struct voicebus *vb, const char *board_name,
goto cleanup;
#if !defined(CONFIG_VOICEBUS_TIMER)
retval = request_irq(vb->pdev->irq, vb_isr, DAHDI_IRQ_SHARED,
retval = request_irq(vb->pdev->irq, vb_isr, DAHDI_IRQ_SHARED_DISABLED,
board_name, vb);
if (retval) {
dev_warn(&vb->pdev->dev, "Failed to request interrupt line.\n");
@@ -2030,7 +2026,7 @@ static int __init voicebus_module_init(void)
* defined, but it will make sure that this module is a dependency of
* dahdi.ko, so that when it is being unloded, this module will be
* unloaded as well. */
dahdi_register_device(NULL, NULL);
dahdi_register(NULL, 0);
spin_lock_init(&loader_list_lock);
return 0;
}

View File

@@ -57,15 +57,6 @@
* (and not tasklet). */
#define CONFIG_VOICEBUS_INTERRUPT
/*
* Enable the following definition in order to disable Active-State Power
* Management on the PCIe bridge for PCIe cards. This has been known to work
* around issues where the BIOS enables it on the cards even though the
* platform does not support it.
*
*/
#undef CONFIG_VOICEBUS_DISABLE_ASPM
/* Define this to use a FIFO for the software echocan reference.
* (experimental) */
#undef CONFIG_VOICEBUS_ECREFERENCE

View File

@@ -35,16 +35,22 @@
#ifdef VOICEBUS_NET_DEBUG
#ifdef HAVE_NETDEV_PRIV
struct voicebus_netdev_priv {
struct voicebus *vb;
};
#endif
static inline struct voicebus *
voicebus_from_netdev(struct net_device *netdev)
{
#ifdef HAVE_NETDEV_PRIV
struct voicebus_netdev_priv *priv;
priv = netdev_priv(netdev);
return priv->vb;
#else
return netdev->priv;
#endif
}
static void *
@@ -203,14 +209,23 @@ int vb_net_register(struct voicebus *vb, const char *board_name)
{
int res;
struct net_device *netdev;
# ifdef HAVE_NETDEV_PRIV
struct voicebus_netdev_priv *priv;
# endif
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
# ifdef HAVE_NETDEV_PRIV
netdev = alloc_netdev(sizeof(*priv), board_name, ether_setup);
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);
priv->vb = vb;
# else
netdev = alloc_netdev(0, vb->board_name, ether_setup);
if (!netdev)
return -ENOMEM;
netdev->priv = vb;
# endif
memcpy(netdev->dev_addr, our_mac, sizeof(our_mac));
# ifdef HAVE_NET_DEVICE_OPS
netdev->netdev_ops = &vb_netdev_ops;

View File

@@ -72,7 +72,7 @@ static int _vpmoct_read(struct vpmoct *vpm, u8 address,
list_del(&cmd->node);
spin_unlock_irqrestore(&vpm->list_lock, flags);
kfree(cmd);
dev_err(vpm->dev, "vpmoct_read_byte cmd timed out\n");
dev_err(vpm->dev, "vpmoct_read_byte cmd timed out :O(\n");
return 0;
}
@@ -443,47 +443,6 @@ static void vpmoct_set_defaults(struct vpmoct *vpm)
vpmoct_write_dword(vpm, 0x30, 0);
}
static const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin";
#if defined(HOTPLUG_FIRMWARE)
static int
vpmoct_request_firmware(const struct firmware **fw, struct device *dev)
{
return request_firmware(fw, FIRMWARE_NAME, dev);
}
static void vpmoct_release_firmware(const struct firmware *fw)
{
release_firmware(fw);
}
#else
static int
vpmoct_request_firmware(const struct firmware **fw_p, struct device *dev)
{
struct firmware *fw;
extern void _binary_dahdi_fw_vpmoct032_bin_size;
extern u8 _binary_dahdi_fw_vpmoct032_bin_start[];
*fw_p = fw = kzalloc(sizeof(*fw), GFP_KERNEL);
if (!fw)
return -ENOMEM;
fw->data = _binary_dahdi_fw_vpmoct032_bin_start;
/* Yes... this is weird. objcopy gives us a symbol containing
the size of the firmware, not a pointer a variable containing the
size. The only way we can get the value of the symbol is to take
its address, so we define it as a pointer and then cast that value
to the proper type. */
fw->size = (size_t) &_binary_dahdi_fw_vpmoct032_bin_size;
return 0;
}
static void vpmoct_release_firmware(const struct firmware *fw)
{
kfree(fw);
}
#endif
/**
* vpmoct_load_flash - Check the current flash version and possibly load.
* @vpm: The VPMOCT032 module to check / load.
@@ -504,9 +463,10 @@ static void vpmoct_load_flash(struct work_struct *data)
const struct firmware *fw;
const struct vpmoct_header *header;
char serial[VPMOCT_SERIAL_SIZE+1];
const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin";
int i;
res = vpmoct_request_firmware(&fw, vpm->dev);
res = request_firmware(&fw, FIRMWARE_NAME, vpm->dev);
if (res) {
dev_warn(vpm->dev,
"vpmoct: Failed to load firmware from userspace! %d\n",
@@ -545,7 +505,7 @@ static void vpmoct_load_flash(struct work_struct *data)
FIRMWARE_NAME);
/* Just use the old version of the fimware. */
vpmoct_release_firmware(fw);
release_firmware(fw);
vpmoct_set_defaults(vpm);
vpmoct_load_complete(work, true);
return;
@@ -554,7 +514,7 @@ static void vpmoct_load_flash(struct work_struct *data)
if (vpm->minor == header->minor &&
vpm->major == header->major) {
/* Proper version is running */
vpmoct_release_firmware(fw);
release_firmware(fw);
vpmoct_set_defaults(vpm);
vpmoct_load_complete(work, true);
return;
@@ -588,14 +548,14 @@ static void vpmoct_load_flash(struct work_struct *data)
if (vpmoct_check_firmware_crc(vpm, fw->size-VPMOCT_FIRM_HEADER_LEN*2,
header->major, header->minor))
goto error;
vpmoct_release_firmware(fw);
release_firmware(fw);
vpmoct_set_defaults(vpm);
vpmoct_load_complete(work, true);
return;
error:
dev_info(vpm->dev, "Unable to load firmware\n");
vpmoct_release_firmware(fw);
release_firmware(fw);
/* TODO: Should we disable module if the firmware doesn't load? */
vpmoct_load_complete(work, false);
return;

View File

@@ -1,7 +1,7 @@
/*
* DAHDI Telephony Interface to VPMADT032 Firmware Loader
*
* Copyright (C) 2008-2012 Digium, Inc. All rights reserved.
* Copyright (C) 2008-2011 Digium, Inc. 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 version 2 as
@@ -38,9 +38,18 @@ logger(const char *format, ...)
int res;
va_list args;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
va_start(args, format);
res = vprintk(format, args);
va_end(args);
#else
char buf[256];
va_start(args, format);
res = vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
printk(KERN_INFO "%s" buf);
#endif
return res;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
else
endif

View File

@@ -2,7 +2,7 @@
* WCB410P Quad-BRI PCI Driver
* Written by Andrew Kohlsmith <akohlsmith@mixdown.ca>
*
* Copyright (C) 2009-2012 Digium, Inc.
* Copyright (C) 2009-2011 Digium, Inc.
* All rights reserved.
*
*/
@@ -35,6 +35,7 @@
#include <linux/spinlock.h>
#include <linux/device.h> /* dev_err() */
#include <linux/interrupt.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_*_user */
#include <linux/workqueue.h> /* work_struct */
#include <linux/timer.h> /* timer_struct */
@@ -90,7 +91,6 @@ static int milliwatt = 0;
static int pedanticpci = 0;
static int teignorered = 0;
static int alarmdebounce = 500;
static int persistentlayer1 = 1;
static int vpmsupport = 1;
static int timer_1_ms = 2000;
static int timer_3_ms = 30000;
@@ -140,7 +140,7 @@ static struct devtype hfc8s_BN = {"BeroNet BN8S0", .ports = 8, .card_type = BN8S
static struct devtype hfc4s_SW = {"Swyx 4xS0 SX2 QuadBri", .ports = 4, .card_type = BSWYX_SX2 };
static struct devtype hfc4s_EV = {"CCD HFC-4S Eval. Board", .ports = 4,
.card_type = QUADBRI_EVAL };
#define CARD_HAS_EC(card) ((card)->card_type == B410P)
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
@@ -1198,6 +1198,7 @@ static int b4xxp_find_sync(struct b4xxp *b4)
return src;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
static ssize_t b4_timing_master_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1225,6 +1226,13 @@ static void remove_sysfs_files(struct b4xxp *b4)
&dev_attr_timing_master);
}
#else
static inline void create_sysfs_files(struct b4xxp *b4) { return; }
static inline void remove_sysfs_files(struct b4xxp *b4) { return; }
#endif /* LINUX_KERNEL > 2.6.18 */
/*
* allocates memory and pretty-prints a given S/T state engine state to it.
* calling routine is responsible for freeing the pointer returned!
@@ -1242,8 +1250,7 @@ static char *hfc_decode_st_state(struct b4xxp *b4, int port, unsigned char state
"?", "?", "?", "?", "?", "?", "?", "?" }
};
str = kmalloc(256, GFP_ATOMIC);
if (!str) {
if (!(str = kmalloc(256, GFP_KERNEL))) {
dev_warn(&b4->pdev->dev, "could not allocate mem for ST state decode string!\n");
return NULL;
}
@@ -1296,9 +1303,6 @@ static void hfc_force_st_state(struct b4xxp *b4, int port, int state, int resume
hfc_handle_state(&b4->spans[port]);
}
static void hfc_stop_st(struct b4xxp_span *s);
static void hfc_start_st(struct b4xxp_span *s);
/* figures out what to do when an S/T port's timer expires. */
static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
{
@@ -1312,15 +1316,10 @@ static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
s->hfc_timer_on[t_no]);
}
/*
* There are four timers associated with every HFC S/T port:
* T1 is used by the NT state machine, and is the maximum time the NT side
* should wait for G3 (active) state.
* T2 is not actually used in the driver, it is handled by the HFC-4S
* internally.
* T3 is used by the TE state machine; it is the maximum time the TE side should
* wait for the INFO4 (activated) signal.
* T4 is a special timer used for debug purposes for monitoring of L1 state
* during activation attempt.
* there are three timers associated with every HFC S/T port.
* T1 is used by the NT state machine, and is the maximum time the NT side should wait for G3 (active) state.
* T2 is not actually used in the driver, it is handled by the HFC-4S internally.
* T3 is used by the TE state machine; it is the maximum time the TE side should wait for the INFO4 (activated) signal.
*/
/* First, disable the expired timer; hfc_force_st_state() may activate it again. */
@@ -1334,14 +1333,7 @@ static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
hfc_force_st_state(b4, s->port, 1, 1);
break;
case HFC_T3: /* switch to F3 (deactivated), resume auto mode */
hfc_stop_st(s);
if (persistentlayer1)
hfc_start_st(s);
break;
case HFC_T4:
hfc_handle_state(s);
s->hfc_timers[HFC_T4] = b4->ticks + 1000;
s->hfc_timer_on[HFC_T4] = 1;
hfc_force_st_state(b4, s->port, 3, 1);
break;
default:
if (printk_ratelimit()) {
@@ -1364,9 +1356,9 @@ static void hfc_update_st_timers(struct b4xxp *b4)
for (i=0; i < b4->numspans; i++) {
s = &b4->spans[i];
for (j = HFC_T1; j < ARRAY_SIZE(s->hfc_timers); j++) {
/* we don't really do timer2, it is expired by the
* state change handler */
for (j=HFC_T1; j <= HFC_T3; j++) {
/* we don't really do timer2, it is expired by the state change handler */
if (j == HFC_T2)
continue;
@@ -1450,7 +1442,6 @@ static void hfc_handle_state(struct b4xxp_span *s)
break;
case 0x7: /* TE state F7: Activated */
s->hfc_timer_on[HFC_T3] = 0;
s->hfc_timer_on[HFC_T4] = 0;
s->newalarm = 0;
break;
}
@@ -1472,17 +1463,14 @@ static void hfc_handle_state(struct b4xxp_span *s)
/* If we're in F3 and receiving INFO0, start T3 and jump to F4 */
if (!nt && (sta == 3) && (state & V_INFO0)) {
if (persistentlayer1) {
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timer_on[HFC_T3] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"port %d: receiving INFO0 in state 3, "
"setting T3 and jumping to F4\n",
s->port + 1);
}
hfc_start_st(s);
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timer_on[HFC_T3] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"port %d: receiving INFO0 in state 3, "
"setting T3 and jumping to F4\n", s->port + 1);
}
hfc_force_st_state(b4, s->port, 4, 1);
}
/* read in R_BERT_STA to determine where our current sync source is */
@@ -1497,24 +1485,6 @@ static void hfc_handle_state(struct b4xxp_span *s)
}
}
static void hfc_stop_all_timers(struct b4xxp_span *s)
{
s->hfc_timer_on[HFC_T4] = 0;
s->hfc_timer_on[HFC_T3] = 0;
s->hfc_timer_on[HFC_T2] = 0;
s->hfc_timer_on[HFC_T1] = 0;
}
static void hfc_stop_st(struct b4xxp_span *s)
{
struct b4xxp *b4 = s->parent;
hfc_stop_all_timers(s);
b4xxp_setreg_ra(b4, R_ST_SEL, s->port, A_ST_WR_STA,
V_ST_ACT_DEACTIVATE);
}
/*
* resets an S/T interface to a given NT/TE mode
*/
@@ -1525,16 +1495,10 @@ static void hfc_reset_st(struct b4xxp_span *s)
b4 = s->parent;
hfc_stop_st(s);
/* force state G0/F0 (reset), then force state 1/2 (deactivated/sensing) */
b4xxp_setreg_ra(b4, R_ST_SEL, s->port, A_ST_WR_STA, V_ST_LD_STA);
flush_pci(); /* make sure write hit hardware */
s->span.alarms = DAHDI_ALARM_RED;
s->newalarm = DAHDI_ALARM_RED;
dahdi_alarm_notify(&s->span);
udelay(10);
/* set up the clock control register. Must be done before we activate the interface. */
@@ -1565,13 +1529,9 @@ static void hfc_start_st(struct b4xxp_span *s)
/* start T1 if in NT mode, T3 if in TE mode */
if (s->te_mode) {
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timers[HFC_T3] = b4->ticks + 500; /* 500ms wait first time, timer_t3_ms afterward. */
s->hfc_timer_on[HFC_T3] = 1;
s->hfc_timer_on[HFC_T1] = 0;
s->hfc_timers[HFC_T4] = b4->ticks + 1000;
s->hfc_timer_on[HFC_T4] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"setting port %d t3 timer to %lu\n",
@@ -1589,6 +1549,17 @@ static void hfc_start_st(struct b4xxp_span *s)
}
}
#if 0 /* TODO: This function is not called anywhere */
static void hfc_stop_st(struct b4xxp_span *s)
{
b4xxp_setreg_ra(s->parent, R_ST_SEL, s->port, A_ST_WR_STA, V_ST_ACT_DEACTIVATE);
s->hfc_timer_on[HFC_T1] = 0;
s->hfc_timer_on[HFC_T2] = 0;
s->hfc_timer_on[HFC_T3] = 0;
}
#endif
/*
* read in the HFC GPIO to determine each port's mode (TE or NT).
* Then, reset and start the port.
@@ -1621,6 +1592,8 @@ static void hfc_init_all_st(struct b4xxp *b4)
dev_info(&b4->pdev->dev,
"Port %d: %s mode\n", i + 1, (nt ? "NT" : "TE"));
hfc_reset_st(s);
hfc_start_st(s);
}
}
@@ -1877,10 +1850,10 @@ static int hdlc_tx_frame(struct b4xxp_span *bspan)
char debugbuf[256];
unsigned long irq_flags;
/* if we're ignoring TE red alarms and we are in alarm, restart the
* S/T state machine */
if (bspan->te_mode && bspan->newalarm != 0)
hfc_start_st(bspan);
/* if we're ignoring TE red alarms and we are in alarm, restart the S/T state machine */
if (bspan->te_mode && teignorered && bspan->newalarm == DAHDI_ALARM_RED) {
hfc_force_st_state(b4, bspan->port, 3, 1);
}
fifo = bspan->fifos[2];
res = dahdi_hdlc_getbuf(bspan->sigchan, buf, &size);
@@ -2232,7 +2205,7 @@ static const char *b4xxp_echocan_name(const struct dahdi_chan *chan)
{
struct b4xxp_span *bspan = container_of(chan->span, struct b4xxp_span,
span);
if (vpmsupport && (B410P == bspan->parent->card_type))
if (bspan->parent->card_type == B410P)
return "LASVEGAS2";
return NULL;
}
@@ -2368,10 +2341,6 @@ static int b4xxp_spanconfig(struct file *file, struct dahdi_span *span,
if (lc->sync)
b4->spans[lc->sync - 1].sync = (span->offset + 1);
hfc_reset_st(bspan);
if (persistentlayer1)
hfc_start_st(bspan);
b4xxp_reset_span(bspan);
/* call startup() manually here, because DAHDI won't call the startup function unless it receives an IOCTL to do so, and dahdi_cfg doesn't. */
@@ -2506,9 +2475,8 @@ static void init_spans(struct b4xxp *b4)
bspan = &b4->spans[i];
bspan->parent = b4;
bspan->span.spantype = (bspan->te_mode)
? SPANTYPE_DIGITAL_BRI_TE
: SPANTYPE_DIGITAL_BRI_NT;
bspan->span.irq = b4->pdev->irq;
bspan->span.spantype = (bspan->te_mode) ? "TE" : "NT";
bspan->span.offset = i;
bspan->span.channels = WCB4XXP_CHANNELS_PER_SPAN;
bspan->span.flags = 0;
@@ -2526,6 +2494,11 @@ static void init_spans(struct b4xxp *b4)
sprintf(bspan->span.name, "B4/%d/%d", b4->cardno, i+1);
sprintf(bspan->span.desc, "B4XXP (PCI) Card %d Span %d", b4->cardno, i+1);
bspan->span.manufacturer = "Digium";
strlcpy(bspan->span.devicetype, b4->variety,
sizeof(bspan->span.devicetype));
sprintf(bspan->span.location, "PCI Bus %02d Slot %02d",
b4->pdev->bus->number, PCI_SLOT(b4->pdev->devfn) + 1);
bspan->span.ops = &b4xxp_span_ops;
/* HDLC stuff */
@@ -2957,27 +2930,14 @@ static int __devinit b4xx_probe(struct pci_dev *pdev, const struct pci_device_id
hfc_init_all_st(b4);
/* initialize the DAHDI structures, and let DAHDI know it has some new hardware to play with */
b4->ddev = dahdi_create_device();
init_spans(b4);
for (x=0; x < b4->numspans; x++) {
struct dahdi_span *const s = &b4->spans[x].span;
list_add_tail(&s->device_node, &b4->ddev->spans);
}
b4->ddev->manufacturer = "Digium";
b4->ddev->devicetype = b4->variety;
b4->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
b4->pdev->bus->number,
PCI_SLOT(b4->pdev->devfn) + 1);
if (!b4->ddev->location) {
ret = -ENOMEM;
goto err_out_del_from_card_array;
}
if (dahdi_register_device(b4->ddev, &b4->pdev->dev)) {
dev_err(&b4->pdev->dev, "Unable to register device.\n");
goto err_out_unreg_spans;
if (dahdi_register(&b4->spans[x].span, 0)) {
dev_err(&b4->pdev->dev,
"Unable to register span %s\n",
b4->spans[x].span.name);
goto err_out_unreg_spans;
}
}
@@ -3013,7 +2973,10 @@ static int __devinit b4xx_probe(struct pci_dev *pdev, const struct pci_device_id
/* 'x' will have the failing span #. (0-3). We need to unregister everything before it. */
err_out_unreg_spans:
dahdi_unregister_device(b4->ddev);
while (x) {
dahdi_unregister(&b4->spans[x].span);
x--;
};
b4xxp_init_stage1(b4); /* full reset, re-init to "no-irq" state */
free_irq(pdev->irq, b4);
@@ -3034,8 +2997,6 @@ err_out_free_mem:
pci_set_drvdata(pdev, NULL);
pci_iounmap(pdev, b4->ioaddr);
pci_iounmap(pdev, b4->addr);
kfree(b4->ddev->location);
dahdi_free_device(b4->ddev);
kfree(b4);
err_out_release_regions:
@@ -3050,11 +3011,14 @@ err_out_disable_pdev:
static void __devexit b4xxp_remove(struct pci_dev *pdev)
{
struct b4xxp *b4 = pci_get_drvdata(pdev);
int i;
if (b4) {
b4->shutdown = 1;
dahdi_unregister_device(b4->ddev);
for (i=b4->numspans - 1; i >= 0; i--) {
dahdi_unregister(&b4->spans[i].span);
}
b4xxp_init_stage1(b4);
remove_sysfs_files(b4);
@@ -3069,8 +3033,6 @@ static void __devexit b4xxp_remove(struct pci_dev *pdev)
tasklet_kill(&b4->b4xxp_tlet);
kfree(b4->ddev->location);
dahdi_free_device(b4->ddev);
kfree(b4);
}
@@ -3152,7 +3114,6 @@ module_param(vpmsupport, int, S_IRUGO);
module_param(timer_1_ms, int, S_IRUGO | S_IWUSR);
module_param(timer_3_ms, int, S_IRUGO | S_IWUSR);
module_param(companding, charp, S_IRUGO);
module_param(persistentlayer1, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "bitmap: 1=general 2=dtmf 4=regops 8=fops 16=ec 32=st state 64=hdlc 128=alarm");
MODULE_PARM_DESC(spanfilter, "debug filter for spans. bitmap: 1=port 1, 2=port 2, 4=port 3, 8=port 4");

View File

@@ -376,7 +376,6 @@
#define HFC_T1 0
#define HFC_T2 1
#define HFC_T3 2
#define HFC_T4 3
#define MAX_SPANS_PER_CARD 8
@@ -397,8 +396,8 @@ struct b4xxp_span {
unsigned long alarmtimer;
int te_mode; /* 1=TE, 0=NT */
unsigned long hfc_timers[4]; /* T1, T2, T3, Fake T4 */
int hfc_timer_on[4]; /* 1=timer active */
unsigned long hfc_timers[WCB4XXP_CHANNELS_PER_SPAN]; /* T1, T2, T3 */
int hfc_timer_on[WCB4XXP_CHANNELS_PER_SPAN]; /* 1=timer active */
int fifos[WCB4XXP_CHANNELS_PER_SPAN]; /* B1, B2, D <--> host fifo numbers */
/* HDLC controller fields */
@@ -475,7 +474,6 @@ struct b4xxp {
/* Flags for our bottom half */
unsigned int shutdown; /* 1=bottom half doesn't process anything, just returns */
struct tasklet_struct b4xxp_tlet;
struct dahdi_device *ddev;
};
/* CPLD access bits */

View File

@@ -135,7 +135,6 @@ static int wecareregs[] =
struct wcfxo {
struct pci_dev *dev;
char *variety;
struct dahdi_device *ddev;
struct dahdi_span span;
struct dahdi_chan _chan;
struct dahdi_chan *chan;
@@ -648,24 +647,19 @@ static const struct dahdi_span_ops wcfxo_span_ops = {
static int wcfxo_initialize(struct wcfxo *wc)
{
wc->ddev = dahdi_create_device();
/* DAHDI stuff */
sprintf(wc->span.name, "WCFXO/%d", wc->pos);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Board %d", wc->variety, wc->pos + 1);
sprintf(wc->chan->name, "WCFXO/%d/%d", wc->pos, 0);
wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
wc->dev->bus->number,
PCI_SLOT(wc->dev->devfn) + 1);
if (!wc->ddev->location)
return -ENOMEM;
wc->ddev->manufacturer = "Digium";
wc->ddev->devicetype = wc->variety;
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
wc->span.manufacturer = "Digium";
strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
wc->chan->sigcap = DAHDI_SIG_FXSKS | DAHDI_SIG_FXSLS | DAHDI_SIG_SF;
wc->chan->chanpos = 1;
wc->span.chans = &wc->chan;
wc->span.channels = 1;
wc->span.irq = wc->dev->irq;
wc->span.flags = DAHDI_FLAG_RBS;
wc->span.deflaw = DAHDI_LAW_MULAW;
#ifdef ENABLE_TASKLETS
@@ -674,8 +668,7 @@ static int wcfxo_initialize(struct wcfxo *wc)
wc->chan->pvt = wc;
wc->span.ops = &wcfxo_span_ops;
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
}
@@ -983,7 +976,7 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
printk(KERN_NOTICE "Failed to initailize DAA, giving up...\n");
wcfxo_stop_dma(wc);
wcfxo_disable_interrupts(wc);
dahdi_unregister_device(wc->ddev);
dahdi_unregister(&wc->span);
free_irq(pdev->irq, wc);
/* Reset PCI chip and registers */
@@ -991,8 +984,6 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
if (wc->freeregion)
release_region(wc->ioaddr, 0xff);
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
kfree(wc);
return -EIO;
}
@@ -1004,11 +995,9 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
static void wcfxo_release(struct wcfxo *wc)
{
dahdi_unregister_device(wc->ddev);
dahdi_unregister(&wc->span);
if (wc->freeregion)
release_region(wc->ioaddr, 0xff);
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
kfree(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}

View File

@@ -159,7 +159,6 @@ struct t1xxp {
unsigned char ec_chunk2[31][DAHDI_CHUNKSIZE];
unsigned char tempo[32];
struct dahdi_span span; /* Span */
struct dahdi_device *ddev;
struct dahdi_chan *chans[31]; /* Channels */
};
@@ -273,11 +272,10 @@ static void t1xxp_release(struct t1xxp *wc)
{
unsigned int x;
dahdi_unregister_device(wc->ddev);
dahdi_unregister(&wc->span);
for (x = 0; x < (wc->ise1 ? 31 : 24); x++) {
kfree(wc->chans[x]);
}
dahdi_free_device(wc->ddev);
kfree(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}
@@ -772,32 +770,26 @@ static int t1xxp_software_init(struct t1xxp *wc)
}
if (x >= WC_MAX_CARDS)
return -1;
wc->ddev = dahdi_create_device();
wc->num = x;
sprintf(wc->span.name, "WCT1/%d", wc->num);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, wc->num);
wc->ddev->manufacturer = "Digium";
wc->ddev->devicetype = wc->variety;
wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
wc->dev->bus->number,
PCI_SLOT(wc->dev->devfn) + 1);
if (!wc->ddev->location)
return -ENOMEM;
wc->span.manufacturer = "Digium";
strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
wc->span.irq = wc->dev->irq;
wc->span.chans = wc->chans;
wc->span.flags = DAHDI_FLAG_RBS;
if (wc->ise1) {
wc->span.channels = 31;
wc->span.deflaw = DAHDI_LAW_ALAW;
wc->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
wc->span.spantype = SPANTYPE_DIGITAL_E1;
wc->span.spantype = "E1";
} else {
wc->span.channels = 24;
wc->span.deflaw = DAHDI_LAW_MULAW;
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
wc->span.spantype = SPANTYPE_DIGITAL_T1;
wc->span.spantype = "T1";
}
for (x=0;x<wc->span.channels;x++) {
sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);
@@ -809,8 +801,7 @@ static int t1xxp_software_init(struct t1xxp *wc)
wc->chans[x]->chanpos = x + 1;
}
wc->span.ops = &t1xxp_span_ops;
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
}
@@ -917,10 +908,10 @@ static void t1xxp_receiveprep(struct t1xxp *wc, int ints)
if (((oldcan & 0xffff0000) >> 16) != CANARY) {
/* Check top part */
if (debug) printk(KERN_DEBUG "Expecting top %04x, got %04x\n", CANARY, (oldcan & 0xffff0000) >> 16);
wc->ddev->irqmisses++;
wc->span.irqmisses++;
} else if ((oldcan & 0xffff) != ((wc->canary - 1) & 0xffff)) {
if (debug) printk(KERN_DEBUG "Expecting bottom %d, got %d\n", wc->canary - 1, oldcan & 0xffff);
wc->ddev->irqmisses++;
wc->span.irqmisses++;
}
for (y=0;y<DAHDI_CHUNKSIZE;y++) {
for (x=0;x<wc->span.channels;x++) {

View File

@@ -2,7 +2,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp.o
FIRM_DIR := ../firmware
EXTRA_CFLAGS += -I$(src)/.. -I$(src)/../oct612x/ $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
# The OCT612X source files are from a vendor drop and we do not want to edit
# them to make this warning go away. Therefore, turn off the
@@ -14,11 +14,10 @@ ifeq ($(HOTPLUG_FIRMWARE),yes)
EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
endif
wct4xxp-objs := base.o vpm450m.o
wct4xxp-objs := base.o vpm450m.o $(shell $(src)/../oct612x/octasic-helper objects ../oct612x)
ifneq ($(HOTPLUG_FIRMWARE),yes)
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.o $(FIRM_DIR)/dahdi-fw-oct6114-256.o
$(warning WARNING: You are compiling firmware into wct4xxp.ko which is not available under the terms of the GPL. It may be a violation of the GPL to distribute the resulting image since it combines both GPL and non-GPL work. You should consult a lawyer of your own before distributing such an image.)
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.o
endif
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-064.o: $(obj)/base.o
@@ -26,6 +25,3 @@ $(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-064.o: $(obj)/base.o
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-128.o: $(obj)/base.o
$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-oct6114-128.o
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-256.o: $(obj)/base.o
$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-oct6114-256.o

View File

@@ -0,0 +1,8 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
else
endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2012 Digium, Inc.
* Copyright (C) 2005-2006 Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
@@ -19,74 +19,110 @@
* this program for more details.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/time.h>
#include <linux/version.h>
#include <dahdi/kernel.h>
#include <stdbool.h>
#include "vpm450m.h"
#include <oct612x.h>
#include "oct6100api/oct6100_api.h"
static int wct4xxp_oct612x_write(struct oct612x_context *context,
u32 address, u16 value)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
#include <linux/config.h>
#endif
/* API for Octasic access */
UINT32 Oct6100UserGetTime(tPOCT6100_GET_TIME f_pTime)
{
struct t4 *wc = dev_get_drvdata(context->dev);
oct_set_reg(wc, address, value);
return 0;
/* Why couldn't they just take a timeval like everyone else? */
struct timeval tv;
unsigned long long total_usecs;
unsigned int mask = ~0;
do_gettimeofday(&tv);
total_usecs = (((unsigned long long)(tv.tv_sec)) * 1000000) +
(((unsigned long long)(tv.tv_usec)));
f_pTime->aulWallTimeUs[0] = (total_usecs & mask);
f_pTime->aulWallTimeUs[1] = (total_usecs >> 32);
return cOCT6100_ERR_OK;
}
static int wct4xxp_oct612x_read(struct oct612x_context *context, u32 address,
u16 *value)
UINT32 Oct6100UserMemSet(PVOID f_pAddress, UINT32 f_ulPattern, UINT32 f_ulLength)
{
struct t4 *wc = dev_get_drvdata(context->dev);
*value = (u16)oct_get_reg(wc, address);
return 0;
memset(f_pAddress, f_ulPattern, f_ulLength);
return cOCT6100_ERR_OK;
}
static int wct4xxp_oct612x_write_smear(struct oct612x_context *context,
u32 address, u16 value, size_t count)
UINT32 Oct6100UserMemCopy(PVOID f_pDestination, const void *f_pSource, UINT32 f_ulLength)
{
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
oct_set_reg(wc, address + (i << 1), value);
return 0;
memcpy(f_pDestination, f_pSource, f_ulLength);
return cOCT6100_ERR_OK;
}
static int wct4xxp_oct612x_write_burst(struct oct612x_context *context,
u32 address, const u16 *buffer,
size_t count)
UINT32 Oct6100UserCreateSerializeObject(tPOCT6100_CREATE_SERIALIZE_OBJECT f_pCreate)
{
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
oct_set_reg(wc, address + (i << 1), buffer[i]);
return 0;
return cOCT6100_ERR_OK;
}
static int wct4xxp_oct612x_read_burst(struct oct612x_context *context,
u32 address, u16 *buffer, size_t count)
UINT32 Oct6100UserDestroySerializeObject(tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
{
struct t4 *wc = dev_get_drvdata(context->dev);
int i;
for (i = 0; i < count; ++i)
buffer[i] = oct_get_reg(wc, address + (i << 1));
return 0;
#ifdef OCTASIC_DEBUG
printk(KERN_DEBUG "I should never be called! (destroy serialize object)\n");
#endif
return cOCT6100_ERR_OK;
}
static const struct oct612x_ops wct4xxp_oct612x_ops = {
.write = wct4xxp_oct612x_write,
.read = wct4xxp_oct612x_read,
.write_smear = wct4xxp_oct612x_write_smear,
.write_burst = wct4xxp_oct612x_write_burst,
.read_burst = wct4xxp_oct612x_read_burst,
};
UINT32 Oct6100UserSeizeSerializeObject(tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserReleaseSerializeObject(tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
{
/* Not needed */
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
{
oct_set_reg(f_pWriteParams->pProcessContext, f_pWriteParams->ulWriteAddress, f_pWriteParams->usWriteData);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParams)
{
unsigned int x;
for (x=0;x<f_pSmearParams->ulWriteLength;x++) {
oct_set_reg(f_pSmearParams->pProcessContext, f_pSmearParams->ulWriteAddress + (x << 1), f_pSmearParams->usWriteData);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x=0;x<f_pBurstParams->ulWriteLength;x++) {
oct_set_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulWriteAddress + (x << 1), f_pBurstParams->pusWriteData[x]);
}
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
{
*(f_pReadParams->pusReadData) = oct_get_reg(f_pReadParams->pProcessContext, f_pReadParams->ulReadAddress);
return cOCT6100_ERR_OK;
}
UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
{
unsigned int x;
for (x=0;x<f_pBurstParams->ulReadLength;x++) {
f_pBurstParams->pusReadData[x] = oct_get_reg(f_pBurstParams->pProcessContext, f_pBurstParams->ulReadAddress + (x << 1));
}
return cOCT6100_ERR_OK;
}
#define SOUT_G168_1100GB_ON 0x40000004
#define SOUT_DTMF_1 0x40000011
@@ -136,17 +172,15 @@ static const struct oct612x_ops wct4xxp_oct612x_ops = {
struct vpm450m {
tPOCT6100_INSTANCE_API pApiInstance;
struct oct612x_context context;
UINT32 aulEchoChanHndl[256];
int chanflags[256];
int ecmode[256];
UINT32 aulEchoChanHndl[128];
int chanflags[128];
int ecmode[128];
int numchans;
};
#define FLAG_DTMF (1 << 0)
#define FLAG_MUTE (1 << 1)
#define FLAG_ECHO (1 << 2)
#define FLAG_ALAW (1 << 3)
static unsigned int tones[] = {
SOUT_DTMF_1,
@@ -186,52 +220,6 @@ static unsigned int tones[] = {
ROUT_G168_1100GB_ON,
};
void vpm450m_set_alaw_companding(struct vpm450m *vpm450m, int channel,
bool alaw)
{
tOCT6100_CHANNEL_MODIFY *modify;
UINT32 ulResult;
UINT32 law_to_use = (alaw) ? cOCT6100_PCM_A_LAW :
cOCT6100_PCM_U_LAW;
if (channel >= ARRAY_SIZE(vpm450m->chanflags)) {
pr_err("Channel out of bounds in %s\n", __func__);
return;
}
/* If we're already in this companding mode, no need to do anything. */
if (alaw == ((vpm450m->chanflags[channel] & FLAG_ALAW) > 0))
return;
modify = kzalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
if (!modify) {
pr_notice("Unable to allocate memory for setec!\n");
return;
}
Oct6100ChannelModifyDef(modify);
modify->ulChannelHndl = vpm450m->aulEchoChanHndl[channel];
modify->fTdmConfigModified = TRUE;
modify->TdmConfig.ulSinPcmLaw = law_to_use;
modify->TdmConfig.ulRinPcmLaw = law_to_use;
modify->TdmConfig.ulSoutPcmLaw = law_to_use;
modify->TdmConfig.ulRoutPcmLaw = law_to_use;
ulResult = Oct6100ChannelModify(vpm450m->pApiInstance, modify);
if (ulResult != GENERIC_OK) {
pr_notice("Failed to apply echo can changes on channel %d %d %08x!\n",
vpm450m->aulEchoChanHndl[channel], channel, ulResult);
} else {
if (debug) {
pr_info("Changed companding on channel %d to %s.\n",
channel, (alaw) ? "alaw" : "ulaw");
}
if (alaw)
vpm450m->chanflags[channel] |= FLAG_ALAW;
else
vpm450m->chanflags[channel] &= ~(FLAG_ALAW);
}
kfree(modify);
}
static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
{
tOCT6100_CHANNEL_MODIFY *modify;
@@ -264,11 +252,6 @@ void vpm450m_setdtmf(struct vpm450m *vpm450m, int channel, int detect, int mute)
tOCT6100_CHANNEL_MODIFY *modify;
UINT32 ulResult;
if (channel >= ARRAY_SIZE(vpm450m->chanflags)) {
pr_err("Channel out of bounds in %s\n", __func__);
return;
}
modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_KERNEL);
if (!modify) {
printk(KERN_NOTICE "wct4xxp: Unable to allocate memory for setdtmf!\n");
@@ -307,11 +290,6 @@ void vpm450m_setdtmf(struct vpm450m *vpm450m, int channel, int detect, int mute)
void vpm450m_setec(struct vpm450m *vpm450m, int channel, int eclen)
{
if (channel >= ARRAY_SIZE(vpm450m->chanflags)) {
pr_err("Channel out of bounds in %s\n", __func__);
return;
}
if (eclen) {
vpm450m->chanflags[channel] |= FLAG_ECHO;
vpm450m_setecmode(vpm450m, channel, cOCT6100_ECHO_OP_MODE_HT_RESET);
@@ -417,18 +395,14 @@ int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start
return 0;
}
unsigned int get_vpm450m_capacity(struct device *device)
unsigned int get_vpm450m_capacity(void *wc)
{
struct oct612x_context context;
UINT32 ulResult;
tOCT6100_API_GET_CAPACITY_PINS CapacityPins;
context.dev = device;
context.ops = &wct4xxp_oct612x_ops;
Oct6100ApiGetCapacityPinsDef(&CapacityPins);
CapacityPins.pProcessContext = &context;
CapacityPins.pProcessContext = wc;
CapacityPins.ulMemoryType = cOCT6100_MEM_TYPE_DDR;
CapacityPins.fEnableMemClkOut = TRUE;
CapacityPins.ulMemClkFreq = cOCT6100_MCLK_FREQ_133_MHZ;
@@ -442,15 +416,12 @@ unsigned int get_vpm450m_capacity(struct device *device)
return CapacityPins.ulCapacityValue;
}
struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
int numspans, const struct firmware *firmware)
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware)
{
tOCT6100_CHIP_OPEN *ChipOpen;
tOCT6100_GET_INSTANCE_SIZE InstanceSize;
tOCT6100_CHANNEL_OPEN *ChannelOpen;
UINT32 ulResult;
const unsigned int mask = (8 == numspans) ? 0x7 : 0x3;
unsigned int sout_stream, rout_stream;
struct vpm450m *vpm450m;
int x,y,law;
@@ -458,8 +429,6 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
return NULL;
memset(vpm450m, 0, sizeof(struct vpm450m));
vpm450m->context.dev = device;
vpm450m->context.ops = &wct4xxp_oct612x_ops;
if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
kfree(vpm450m);
@@ -488,7 +457,7 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
ChipOpen->ulUpclkFreq = cOCT6100_UPCLK_FREQ_33_33_MHZ;
Oct6100GetInstanceSizeDef(&InstanceSize);
ChipOpen->pProcessContext = &vpm450m->context;
ChipOpen->pProcessContext = wc;
ChipOpen->pbyImageFile = firmware->data;
ChipOpen->ulImageSize = firmware->size;
@@ -498,22 +467,15 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
ChipOpen->ulMemoryType = cOCT6100_MEM_TYPE_DDR;
ChipOpen->ulMemoryChipSize = cOCT6100_MEMORY_CHIP_SIZE_32MB;
ChipOpen->ulNumMemoryChips = 1;
ChipOpen->ulMaxTdmStreams = 4;
ChipOpen->aulTdmStreamFreqs[0] = cOCT6100_TDM_STREAM_FREQ_8MHZ;
ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
ChipOpen->ulMaxFlexibleConfParticipants = 0;
ChipOpen->ulMaxConfBridges = 0;
ChipOpen->ulMaxRemoteDebugSessions = 0;
ChipOpen->fEnableChannelRecording = FALSE;
ChipOpen->ulSoftToneEventsBufSize = 64;
if (vpm450m->numchans <= 128) {
ChipOpen->ulMaxTdmStreams = 4;
ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_FALLING_EDGE;
} else {
ChipOpen->ulMaxTdmStreams = 32;
ChipOpen->fEnableFastH100Mode = TRUE;
ChipOpen->ulTdmSampling = cOCT6100_TDM_SAMPLE_AT_RISING_EDGE;
}
#if 0
ChipOpen->fEnableAcousticEcho = TRUE;
#endif
@@ -545,11 +507,7 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
kfree(ChannelOpen);
return NULL;
}
sout_stream = (8 == numspans) ? 29 : 2;
rout_stream = (8 == numspans) ? 24 : 3;
for (x = 0; x < ((8 == numspans) ? 256 : 128); x++) {
for (x = 0; x < ARRAY_SIZE(vpm450m->aulEchoChanHndl); x++) {
/* execute this loop always on 4 span cards but
* on 2 span cards only execute for the channels related to our spans */
if (( numspans > 2) || ((x & 0x03) <2)) {
@@ -557,13 +515,10 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
* therefore, the lower 2 bits tell us which span this
* timeslot/channel
*/
if (isalaw[x & mask]) {
if (isalaw[x & 0x03])
law = cOCT6100_PCM_A_LAW;
vpm450m->chanflags[x] |= FLAG_ALAW;
} else {
else
law = cOCT6100_PCM_U_LAW;
vpm450m->chanflags[x] &= ~(FLAG_ALAW);
}
Oct6100ChannelOpenDef(ChannelOpen);
ChannelOpen->pulChannelHndl = &vpm450m->aulEchoChanHndl[x];
ChannelOpen->ulUserChanId = x;
@@ -574,13 +529,11 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
ChannelOpen->TdmConfig.ulSinStream = 1;
ChannelOpen->TdmConfig.ulSinTimeslot = x;
ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
ChannelOpen->TdmConfig.ulSoutStream = sout_stream;
ChannelOpen->TdmConfig.ulSoutStream = 2;
ChannelOpen->TdmConfig.ulSoutTimeslot = x;
#if 1
ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
ChannelOpen->TdmConfig.ulRoutStream = rout_stream;
ChannelOpen->TdmConfig.ulRoutStream = 3;
ChannelOpen->TdmConfig.ulRoutTimeslot = x;
#endif
ChannelOpen->VqeConfig.fEnableNlp = TRUE;
ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
@@ -590,7 +543,7 @@ struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, ChannelOpen);
if (ulResult != GENERIC_OK) {
printk(KERN_NOTICE "Failed to open channel %d %x!\n", x, ulResult);
printk(KERN_NOTICE "Failed to open channel %d!\n", x);
continue;
}
for (y = 0; y < ARRAY_SIZE(tones); y++) {

View File

@@ -25,7 +25,6 @@
#include <linux/firmware.h>
struct t4;
struct vpm450m;
/* From driver */
@@ -33,17 +32,12 @@ unsigned int oct_get_reg(void *data, unsigned int reg);
void oct_set_reg(void *data, unsigned int reg, unsigned int val);
/* From vpm450m */
struct vpm450m *init_vpm450m(struct device *device, int *isalaw,
int numspans, const struct firmware *firmware);
unsigned int get_vpm450m_capacity(struct device *device);
struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct firmware *firmware);
unsigned int get_vpm450m_capacity(void *wc);
void vpm450m_setec(struct vpm450m *instance, int channel, int eclen);
void vpm450m_setdtmf(struct vpm450m *instance, int channel, int dtmfdetect, int dtmfmute);
int vpm450m_checkirq(struct vpm450m *vpm450m);
int vpm450m_getdtmf(struct vpm450m *vpm450m, int *channel, int *tone, int *start);
void release_vpm450m(struct vpm450m *instance);
void vpm450m_set_alaw_companding(struct vpm450m *vpm450m,
int channel, bool alaw);
extern int debug;
#endif

View File

@@ -54,12 +54,6 @@
#define FRMR_SIC3 0x40
#define FRMR_CMR1 0x44
#define FRMR_CMR2 0x45
/* OctalFALC Only */
#define FRMR_CMR4 0x41
#define FRMR_CMR5 0x42
#define FRMR_CMR6 0x43
#define FRMR_GPC2 0x8a
/* End Octal */
#define FRMR_GCR 0x46
#define FRMR_ISR0 0x68
#define FRMR_ISR0_RME 0x80
@@ -82,13 +76,6 @@
#define FRMR_CIS_GIS2 0x02
#define FRMR_CIS_GIS3 0x04
#define FRMR_CIS_GIS4 0x08
/* CIS - Octal falc bits */
#define FRMR_CIS_GIS5 0x10
#define FRMR_CIS_GIS6 0x20
#define FRMR_CIS_GIS7 0x40
#define FRMR_CIS_GIS8 0x80
#define FRMR_CMDR 0x02
#define FRMR_CMDR_SRES 0x01
#define FRMR_CMDR_XRES 0x10
@@ -126,11 +113,6 @@ struct t4_regs {
unsigned char regs[NUM_REGS];
};
struct t4_reg {
unsigned int reg;
unsigned int val;
};
#define T4_CHECK_VPM 0
#define T4_LOADING_FW 1
#define T4_STOP_DMA 2
@@ -138,7 +120,5 @@ struct t4_reg {
#define T4_CHANGE_LATENCY 4
#define T4_IGNORE_LATENCY 5
#define WCT4_GET_REGS _IOW(DAHDI_CODE, 60, struct t4_regs)
#define WCT4_GET_REG _IOW(DAHDI_CODE, 61, struct t4_reg)
#define WCT4_SET_REG _IOW(DAHDI_CODE, 62, struct t4_reg)
#define WCT4_GET_REGS _IOW (DAHDI_CODE, 60, struct t4_regs)

View File

@@ -0,0 +1,7 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
else
endif

View File

@@ -1,6 +1,6 @@
/* Wildcard TC400B Driver
*
* Copyright (C) 2006-2012, Digium, Inc.
* Copyright (C) 2006-2010, Digium, Inc.
*
* All rights reserved.
*
@@ -42,7 +42,11 @@
#include "dahdi/kernel.h"
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
#include <asm/io.h>
#else
#include <linux/io.h>
#endif
/* COMPILE TIME OPTIONS =================================================== */
@@ -69,6 +73,27 @@
dev_info(&(wc)->pdev->dev, _fmt, ## _args); \
} \
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
#ifndef WARN_ON_ONCE
#define WARN_ON_ONCE(__condition) do { \
static int __once = 1; \
if (unlikely(__condition)) { \
if (__once) { \
__once = 0; \
WARN_ON(0); \
} \
} \
} while (0)
#endif
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
/* also added in RHEL kernels with the OpenInfiniband backport: */
#if LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 9) || !defined(DEFINE_SPINLOCK)
typedef unsigned gfp_t; /* Added in 2.6.14 */
#endif
#endif
/* define CONFIG_WCTC4XXP_POLLING to operate in a pure polling mode. This is
* was placed in as a debugging tool for a particluar system that wasn't
@@ -369,16 +394,22 @@ struct wcdte {
#endif
};
#ifdef HAVE_NETDEV_PRIV
struct wcdte_netdev_priv {
struct wcdte *wc;
};
#endif
static inline struct wcdte *
wcdte_from_netdev(struct net_device *netdev)
{
#ifdef HAVE_NETDEV_PRIV
struct wcdte_netdev_priv *priv;
priv = netdev_priv(netdev);
return priv->wc;
#else
return netdev->priv;
#endif
}
@@ -463,7 +494,6 @@ wctc4xxp_skb_to_cmd(struct wcdte *wc, const struct sk_buff *skb)
return cmd;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
static void
wctc4xxp_net_set_multi(struct net_device *netdev)
{
@@ -471,15 +501,6 @@ wctc4xxp_net_set_multi(struct net_device *netdev)
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
__func__, netdev->promiscuity);
}
#else
static void
wctc4xxp_set_rx_mode(struct net_device *netdev)
{
struct wcdte *wc = wcdte_from_netdev(netdev);
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
__func__, netdev->promiscuity);
}
#endif
static int
wctc4xxp_net_up(struct net_device *netdev)
@@ -643,11 +664,7 @@ wctc4xxp_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
#ifdef HAVE_NET_DEVICE_OPS
static const struct net_device_ops wctc4xxp_netdev_ops = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
.ndo_set_multicast_list = &wctc4xxp_net_set_multi,
#else
.ndo_set_rx_mode = &wctc4xxp_set_rx_mode,
#endif
.ndo_open = &wctc4xxp_net_up,
.ndo_stop = &wctc4xxp_net_down,
.ndo_start_xmit = &wctc4xxp_net_hard_start_xmit,
@@ -669,14 +686,23 @@ wctc4xxp_net_register(struct wcdte *wc)
{
int res;
struct net_device *netdev;
# ifdef HAVE_NETDEV_PRIV
struct wcdte_netdev_priv *priv;
# endif
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
# ifdef HAVE_NETDEV_PRIV
netdev = alloc_netdev(sizeof(*priv), wc->board_name, ether_setup);
if (!netdev)
return -ENOMEM;
priv = netdev_priv(netdev);
priv->wc = wc;
# else
netdev = alloc_netdev(0, wc->board_name, ether_setup);
if (!netdev)
return -ENOMEM;
netdev->priv = wc;
# endif
memcpy(netdev->dev_addr, our_mac, sizeof(our_mac));
# ifdef HAVE_NET_DEVICE_OPS
@@ -866,7 +892,6 @@ wctc4xxp_initialize_descriptor_ring(struct pci_dev *pdev,
memset(dr->desc, 0, (sizeof(*d) + dr->padding) * DRING_SIZE);
for (i = 0; i < DRING_SIZE; ++i) {
d = wctc4xxp_descriptor(dr, i);
memset(d, 0, sizeof(*d));
d->des1 = cpu_to_le32(des1);
}
@@ -2148,13 +2173,12 @@ wctc4xxp_write(struct file *file, const char __user *frame,
}
if (DAHDI_FORMAT_G723_1 == dtc->srcfmt) {
if ((G723_5K_BYTES != count) && (G723_6K_BYTES != count) &&
(G723_SID_BYTES != count)) {
if ((G723_5K_BYTES != count) && (G723_6K_BYTES != count)) {
DTE_DEBUG(DTE_DEBUG_GENERAL,
"Trying to transcode packet into G723 format " \
"that is %Zu bytes instead of the expected " \
"%d/%d/%d bytes.\n", count, G723_5K_BYTES,
G723_6K_BYTES, G723_SID_BYTES);
"%d/%d bytes.\n", count, G723_5K_BYTES,
G723_6K_BYTES);
return -EINVAL;
}
cpvt->timestamp += G723_SAMPLES;
@@ -3312,7 +3336,6 @@ wctc4xxp_watchdog(unsigned long data)
"Board malfunctioning. " \
"Halting operation.\n");
reschedule_timer = 0;
spin_lock(&wc->cmd_list_lock);
break;
}
/* ERROR: We've retried the command and

View File

@@ -205,7 +205,6 @@ struct wctdm {
struct pci_dev *dev;
char *variety;
struct dahdi_span span;
struct dahdi_device *ddev;
unsigned char ios;
int usecount;
unsigned int intcount;
@@ -1711,7 +1710,7 @@ static int wctdm_init_voicedaa(struct wctdm *wc, int card, int fast, int manual,
/* Misc. DAA parameters */
if (fastpickup)
reg31 = 0xe3;
reg31 = 0xb3;
else
reg31 = 0xa3;
@@ -2363,26 +2362,13 @@ static int wctdm_initialize(struct wctdm *wc)
{
int x;
wc->ddev = dahdi_create_device();
if (!wc->ddev)
return -ENOMEM;
/* DAHDI stuff */
sprintf(wc->span.name, "WCTDM/%d", wc->pos);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Board %d", wc->variety, wc->pos + 1);
wc->ddev->location = kasprintf(GFP_KERNEL,
"PCI Bus %02d Slot %02d",
wc->dev->bus->number,
PCI_SLOT(wc->dev->devfn) + 1);
if (!wc->ddev->location) {
dahdi_free_device(wc->ddev);
wc->ddev = NULL;
return -ENOMEM;
}
wc->ddev->manufacturer = "Digium";
wc->ddev->devicetype = wc->variety;
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
wc->span.manufacturer = "Digium";
strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
if (alawoverride) {
printk(KERN_INFO "ALAW override parameter detected. Device will be operating in ALAW\n");
wc->span.deflaw = DAHDI_LAW_ALAW;
@@ -2398,15 +2384,12 @@ static int wctdm_initialize(struct wctdm *wc)
}
wc->span.chans = wc->chans;
wc->span.channels = NUM_CARDS;
wc->span.irq = wc->dev->irq;
wc->span.flags = DAHDI_FLAG_RBS;
wc->span.ops = &wctdm_span_ops;
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
wc->ddev = NULL;
return -1;
}
return 0;
@@ -2694,9 +2677,7 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
release_region(wc->ioaddr, 0xff);
pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)wc->writechunk, wc->writedma);
pci_set_drvdata(pdev, NULL);
dahdi_unregister_device(wc->ddev);
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
dahdi_unregister(&wc->span);
kfree(wc);
return -EIO;
@@ -2727,14 +2708,10 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
static void wctdm_release(struct wctdm *wc)
{
dahdi_unregister_device(wc->ddev);
dahdi_unregister(&wc->span);
if (wc->freeregion)
release_region(wc->ioaddr, 0xff);
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
kfree(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}

View File

@@ -0,0 +1,6 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
endif

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,7 @@
* \brief Default ringer debounce (in ms)
*/
#define DEFAULT_RING_DEBOUNCE 1024
#define POLARITY_DEBOUNCE 64 /* Polarity debounce (in ms) */
#define OHT_TIMER 6000 /* How long after RING to retain OHT */
@@ -84,6 +85,7 @@
#define NUM_CAL_REGS 12
#define ISR_COMMANDS 2
#define QRV_DEBOUNCETIME 20
#define VPM150M_HPI_CONTROL 0x00
@@ -105,32 +107,10 @@ struct calregs {
enum battery_state {
BATTERY_UNKNOWN = 0,
BATTERY_DEBOUNCING_PRESENT,
BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM,
BATTERY_DEBOUNCING_PRESENT_ALARM,
BATTERY_PRESENT,
BATTERY_DEBOUNCING_LOST,
BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM,
BATTERY_DEBOUNCING_LOST_ALARM,
BATTERY_LOST,
};
enum ring_detector_state {
RINGOFF = 0,
DEBOUNCING_RINGING_POSITIVE,
DEBOUNCING_RINGING_NEGATIVE,
RINGING,
DEBOUNCING_RINGOFF,
};
enum polarity_state {
UNKNOWN_POLARITY = 0,
POLARITY_DEBOUNCE_POSITIVE,
POLARITY_POSITIVE,
POLARITY_DEBOUNCE_NEGATIVE,
POLARITY_NEGATIVE,
};
struct wctdm_cmd {
struct list_head node;
struct completion *complete;
@@ -166,26 +146,29 @@ struct wctdm_chan {
};
struct fxo {
enum ring_detector_state ring_state:4;
enum battery_state battery_state:4;
enum polarity_state polarity_state:4;
u8 ring_polarity_change_count:4;
u8 hook_ring_shadow;
s8 line_voltage_status;
int wasringing;
int lastrdtx;
int lastrdtx_count;
int ringdebounce;
int offhook;
int battdebounce;
int battalarm;
enum battery_state battery;
int lastpol;
int polarity;
int polaritydebounce;
int neonmwi_state;
int neonmwi_last_voltage;
unsigned int neonmwi_debounce;
unsigned int neonmwi_offcounter;
unsigned long display_fxovoltage;
unsigned long ringdebounce_timer;
unsigned long battdebounce_timer;
unsigned long poldebounce_timer;
};
struct fxs {
u8 oht_active:1;
u8 off_hook:1;
int oldrxhook;
int debouncehook;
int lastrxhook;
int debounce;
int ohttimer;
int idletxhookstate; /* IDLE changing hook state */
/* lasttxhook reflects the last value written to the proslic's reg
* 64 (LINEFEED_CONTROL) in bits 0-2. Bit 4 indicates if the last
@@ -197,18 +180,13 @@ struct fxs {
* voicebus ISR.
*/
int lasttxhook;
u8 linefeed_control_shadow;
u8 hook_state_shadow;
int oppending_ms;
int palarms;
struct dahdi_vmwi_info vmwisetting;
int vmwi_active_messages;
int vmwi_linereverse;
int reversepolarity; /* polarity reversal */
struct calregs calregs;
unsigned long check_alarm;
unsigned long check_proslic;
unsigned long oppending_timeout;
unsigned long ohttimer;
};
struct qrv {
@@ -225,7 +203,6 @@ struct qrv {
int radmode;
signed short rxgain;
signed short txgain;
u8 isrshadow[3];
};
enum module_type {
@@ -238,7 +215,7 @@ enum module_type {
};
struct wctdm_module {
union modtypes {
union {
struct fxo fxo;
struct fxs fxs;
struct qrv qrv;
@@ -250,6 +227,7 @@ struct wctdm_module {
struct list_head active_cmds;
u8 offsets[3];
u8 subaddr;
u8 isrshadow[ISR_COMMANDS];
u8 card;
enum module_type type;
@@ -264,7 +242,7 @@ struct wctdm {
spinlock_t frame_list_lock;
struct list_head frame_list;
unsigned long framecount;
unsigned int intcount;
unsigned char txident;
unsigned char rxident;
@@ -277,7 +255,6 @@ struct wctdm {
spinlock_t reglock; /* held when accessing anything affecting the module array */
wait_queue_head_t regq;
struct list_head free_isr_commands;
struct wctdm_module mods[NUM_MODULES];
@@ -299,7 +276,6 @@ struct wctdm {
int not_ready; /* 0 when the entire card is ready to go */
unsigned long checkflag; /* Internal state flags and task bits */
int companding;
struct dahdi_device *ddev;
};
static inline bool is_initialized(struct wctdm *wc)

View File

@@ -2150,9 +2150,7 @@ static int b400m_set_ntte(struct b400m_span *bspan, int te_mode, int term_on)
int all_modes = 0, all_terms = 0;
int i;
bspan->wspan->span.spantype = (te_mode > 0)
? SPANTYPE_DIGITAL_BRI_TE
: SPANTYPE_DIGITAL_BRI_NT;
bspan->wspan->span.spantype = (te_mode > 0) ? "TE" : "NT";
bspan->te_mode = te_mode;
bspan->term_on = term_on;

View File

@@ -174,7 +174,6 @@ struct t1 {
unsigned char ec_chunk1[32][DAHDI_CHUNKSIZE];
unsigned char ec_chunk2[32][DAHDI_CHUNKSIZE];
unsigned char tempo[33];
struct dahdi_device *ddev;
struct dahdi_span span; /* Span */
struct dahdi_chan *chans[32]; /* Channels */
};
@@ -341,12 +340,10 @@ static void t1xxp_release(struct t1 *wc)
{
unsigned int x;
dahdi_unregister_device(wc->ddev);
dahdi_unregister(&wc->span);
for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
kfree(wc->chans[x]);
}
kfree(wc->ddev->location);
dahdi_free_device(wc->ddev);
kfree(wc);
printk(KERN_INFO "Freed a Wildcard\n");
}
@@ -979,33 +976,27 @@ static int t1xxp_software_init(struct t1 *wc)
}
if (x >= WC_MAX_CARDS)
return -1;
wc->ddev = dahdi_create_device();
t4_serial_setup(wc);
wc->num = x;
sprintf(wc->span.name, "WCT1/%d", wc->num);
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, wc->num);
wc->ddev->manufacturer = "Digium";
wc->ddev->devicetype = wc->variety;
wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
wc->dev->bus->number,
PCI_SLOT(wc->dev->devfn) + 1);
if (!wc->ddev->location)
return -ENOMEM;
wc->span.manufacturer = "Digium";
strlcpy(wc->span.devicetype, wc->variety, sizeof(wc->span.devicetype));
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
"PCI Bus %02d Slot %02d", wc->dev->bus->number, PCI_SLOT(wc->dev->devfn) + 1);
wc->span.irq = wc->dev->irq;
if (wc->spantype == TYPE_E1) {
if (unchannelized)
wc->span.channels = 32;
else
wc->span.channels = 31;
wc->span.deflaw = DAHDI_LAW_ALAW;
wc->span.spantype = SPANTYPE_DIGITAL_E1;
wc->span.spantype = "E1";
wc->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
} else {
wc->span.channels = 24;
wc->span.deflaw = DAHDI_LAW_MULAW;
wc->span.spantype = SPANTYPE_DIGITAL_T1;
wc->span.spantype = "T1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
}
wc->span.chans = wc->chans;
@@ -1020,8 +1011,7 @@ static int t1xxp_software_init(struct t1 *wc)
wc->chans[x]->chanpos = x + 1;
}
wc->span.ops = &t1xxp_span_ops;
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
if (dahdi_register(&wc->span, 0)) {
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
return -1;
}
@@ -1128,10 +1118,10 @@ static void t1xxp_receiveprep(struct t1 *wc, int ints)
if (((oldcan & 0xffff0000) >> 16) != CANARY) {
/* Check top part */
if (debug) printk(KERN_DEBUG "Expecting top %04x, got %04x\n", CANARY, (oldcan & 0xffff0000) >> 16);
wc->ddev->irqmisses++;
wc->span.irqmisses++;
} else if ((oldcan & 0xffff) != ((wc->canary - 1) & 0xffff)) {
if (debug) printk(KERN_DEBUG "Expecting bottom %d, got %d\n", wc->canary - 1, oldcan & 0xffff);
wc->ddev->irqmisses++;
wc->span.irqmisses++;
}
for (y=0;y<DAHDI_CHUNKSIZE;y++) {
for (x=0;x<wc->span.channels;x++) {

View File

@@ -0,0 +1,6 @@
ifdef KBUILD_EXTMOD
# We only get here on kernels 2.6.0-2.6.9 .
# For newer kernels, Kbuild will be included directly by the kernel
# build system.
include $(src)/Kbuild
endif

File diff suppressed because it is too large Load Diff

View File

@@ -74,11 +74,8 @@
#define CMD_BYTE(slot, a, is_vpm) (slot*6)+(a*2)+is_vpm /* only even slots */
//TODO: make a separate macro
enum linemode {
T1 = 1,
E1,
J1,
};
#define TYPE_T1 1
#define TYPE_E1 2
struct command {
struct list_head node;
@@ -97,6 +94,7 @@ struct t1 {
unsigned char txident;
unsigned char rxident;
unsigned char statreg; /* bit 0 = vpmadt032 int */
int spantype;
struct {
unsigned int nmf:1;
unsigned int sendingyellow:1;
@@ -114,12 +112,10 @@ struct t1 {
#define INITIALIZED 1
#define SHUTDOWN 2
#define READY 3
#define IOERROR 4
unsigned long bit_flags;
unsigned long alarmtimer;
unsigned char ledstate;
unsigned char vpm_check_count;
struct dahdi_device *ddev;
struct dahdi_span span; /* Span */
struct dahdi_chan *chans[32]; /* Channels */
struct dahdi_echocan_state *ec[32]; /* Echocan state for channels */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,951 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 26)
#define HAVE_RATELIMIT
#include <linux/ratelimit.h>
#endif
#include <dahdi/kernel.h>
#include <stdbool.h>
#include "wcxb.h"
#include "wcxb_spi.h"
#include "wcxb_flash.h"
/* The definition for Surprise Down was added in Linux 3.6 in (a0dee2e PCI: misc
* pci_reg additions). It may be backported though so we won't check for the
* version. */
#ifndef PCI_ERR_UNC_SURPDN
#define PCI_ERR_UNC_SURPDN 0x20
#endif
/* FPGA Status definitions */
#define OCT_CPU_RESET (1 << 0)
#define OCT_CPU_DRAM_CKE (1 << 1)
#define STATUS_LED_GREEN (1 << 9)
#define STATUS_LED_RED (1 << 10)
#define FALC_CPU_RESET (1 << 11)
/* Descriptor ring definitions */
#define DRING_SIZE (1 << 7) /* Must be in multiples of 2 */
#define DRING_SIZE_MASK (DRING_SIZE-1)
#define DESC_EOR (1 << 0)
#define DESC_INT (1 << 1)
#define DESC_OWN (1 << 31)
#define DESC_DEFAULT_STATUS 0xdeadbeef
#define DMA_CHAN_SIZE 128
/* Echocan definitions */
#define OCT_OFFSET (xb->membase + 0x10000)
#define OCT_CONTROL_REG (OCT_OFFSET + 0)
#define OCT_DATA_REG (OCT_OFFSET + 0x4)
#define OCT_ADDRESS_HIGH_REG (OCT_OFFSET + 0x8)
#define OCT_ADDRESS_LOW_REG (OCT_OFFSET + 0xa)
#define OCT_DIRECT_WRITE_MASK 0x3001
#define OCT_INDIRECT_READ_MASK 0x0101
#define OCT_INDIRECT_WRITE_MASK 0x3101
/* DMA definitions */
#define TDM_DRING_ADDR 0x2000
#define TDM_CONTROL (TDM_DRING_ADDR + 0x4)
#define ENABLE_ECHOCAN_TDM (1 << 0)
#define TDM_RECOVER_CLOCK (1 << 1)
#define ENABLE_DMA (1 << 2)
#define DMA_RUNNING (1 << 3)
#define DMA_LOOPBACK (1 << 4)
#define AUTHENTICATED (1 << 5)
#define TDM_VERSION (TDM_DRING_ADDR + 0x24)
/* Interrupt definitions */
#define INTERRUPT_CONTROL 0x300
#define ISR (INTERRUPT_CONTROL + 0x0)
#define IPR (INTERRUPT_CONTROL + 0x4)
#define IER (INTERRUPT_CONTROL + 0x8)
#define IAR (INTERRUPT_CONTROL + 0xc)
#define SIE (INTERRUPT_CONTROL + 0x10)
#define CIE (INTERRUPT_CONTROL + 0x14)
#define IVR (INTERRUPT_CONTROL + 0x18)
#define MER (INTERRUPT_CONTROL + 0x1c)
#define MER_ME (1<<0)
#define MER_HIE (1<<1)
#define DESC_UNDERRUN (1<<0)
#define DESC_COMPLETE (1<<1)
#define OCT_INT (1<<2)
#define FALC_INT (1<<3)
#define SPI_INT (1<<4)
#define FLASH_SPI_BASE 0x200
struct wcxb_hw_desc {
volatile __be32 status;
__be32 tx_buf;
__be32 rx_buf;
volatile __be32 control;
} __packed;
struct wcxb_meta_desc {
void *tx_buf_virt;
void *rx_buf_virt;
};
static inline bool wcxb_is_pcie(const struct wcxb *xb)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33)
return pci_is_pcie(xb->pdev);
#else
#ifndef WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
return (xb->pdev->is_pcie > 0);
#else
return (xb->flags.is_pcie > 0);
#endif
#endif
}
static const unsigned int CLK_SRC_MASK = ((1 << 13) | (1 << 12) | (1 << 1));
enum wcxb_clock_sources wcxb_get_clksrc(struct wcxb *xb)
{
static const u32 SELF = 0x0;
static const u32 RECOVER = (1 << 1);
static const u32 SLAVE = (1 << 12) | (1 << 1);
unsigned long flags;
u32 reg;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase + TDM_CONTROL) & CLK_SRC_MASK;
spin_unlock_irqrestore(&xb->lock, flags);
if (SELF == reg)
return WCXB_CLOCK_SELF;
else if (RECOVER == reg)
return WCXB_CLOCK_RECOVER;
else if (SLAVE == reg)
return WCXB_CLOCK_SLAVE;
else
WARN_ON(1);
return WCXB_CLOCK_SELF;
}
void wcxb_set_clksrc(struct wcxb *xb, enum wcxb_clock_sources clksrc)
{
unsigned long flags;
u32 clkbits = 0;
switch (clksrc) {
case WCXB_CLOCK_RECOVER:
if (xb->flags.drive_timing_cable)
clkbits = (1<<13) | (1 << 1);
else
clkbits = (1 << 1);
break;
case WCXB_CLOCK_SELF:
if (xb->flags.drive_timing_cable)
clkbits = (1<<13);
else
clkbits = 0;
break;
case WCXB_CLOCK_SLAVE:
/* When we're slave, do not ever drive the timing cable. */
clkbits = (1<<12) | (1 << 1);
break;
};
/* set new clock select */
spin_lock_irqsave(&xb->lock, flags);
if (!wcxb_is_stopped(xb)) {
dev_err(&xb->pdev->dev, "ERROR: Cannot set clock source while DMA engine is running.\n");
} else {
u32 reg;
reg = ioread32be(xb->membase + TDM_CONTROL);
reg &= ~CLK_SRC_MASK;
reg |= (clkbits & CLK_SRC_MASK);
iowrite32be(reg, xb->membase + TDM_CONTROL);
}
spin_unlock_irqrestore(&xb->lock, flags);
}
void wcxb_enable_echocan(struct wcxb *xb)
{
u32 reg;
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase + TDM_CONTROL);
reg |= ENABLE_ECHOCAN_TDM;
iowrite32be(reg, xb->membase + TDM_CONTROL);
spin_unlock_irqrestore(&xb->lock, flags);
}
void wcxb_disable_echocan(struct wcxb *xb)
{
u32 reg;
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase + TDM_CONTROL);
reg &= ~ENABLE_ECHOCAN_TDM;
iowrite32be(reg, xb->membase + TDM_CONTROL);
spin_unlock_irqrestore(&xb->lock, flags);
}
void wcxb_reset_echocan(struct wcxb *xb)
{
unsigned long flags;
int reg;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase);
iowrite32be((reg & ~OCT_CPU_RESET), xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
msleep_interruptible(1);
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase);
iowrite32be((reg | OCT_CPU_RESET), xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
dev_dbg(&xb->pdev->dev, "Reset octasic\n");
}
bool wcxb_is_echocan_present(struct wcxb *xb)
{
return 0x1 == ioread16be(OCT_CONTROL_REG);
}
void wcxb_enable_echocan_dram(struct wcxb *xb)
{
unsigned long flags;
int reg;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase);
iowrite32be((reg | OCT_CPU_DRAM_CKE), xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
}
u16 wcxb_get_echocan_reg(struct wcxb *xb, u32 address)
{
uint16_t highaddress = ((address >> 20) & 0xfff);
uint16_t lowaddress = ((address >> 4) & 0xfffff);
unsigned long stop = jiffies + HZ/10;
unsigned long flags;
u16 ret;
spin_lock_irqsave(&xb->lock, flags);
iowrite16be(highaddress, OCT_ADDRESS_HIGH_REG);
iowrite16be(lowaddress, OCT_ADDRESS_LOW_REG);
iowrite16be(OCT_INDIRECT_READ_MASK | ((address & 0xe) << 8),
OCT_CONTROL_REG);
do {
ret = ioread16be(OCT_CONTROL_REG);
} while ((ret & (1<<8)) && time_before(jiffies, stop));
WARN_ON_ONCE(time_after_eq(jiffies, stop));
ret = ioread16be(OCT_DATA_REG);
spin_unlock_irqrestore(&xb->lock, flags);
return ret;
}
void wcxb_set_echocan_reg(struct wcxb *xb, u32 address, u16 val)
{
unsigned long flags;
uint16_t ret;
uint16_t highaddress = ((address >> 20) & 0xfff);
uint16_t lowaddress = ((address >> 4) & 0xffff);
unsigned long stop = jiffies + HZ/10;
spin_lock_irqsave(&xb->lock, flags);
iowrite16be(highaddress, OCT_ADDRESS_HIGH_REG);
iowrite16be(lowaddress, OCT_ADDRESS_LOW_REG);
iowrite16be(val, OCT_DATA_REG);
iowrite16be(OCT_INDIRECT_WRITE_MASK | ((address & 0xe) << 8),
OCT_CONTROL_REG);
/* No write should take longer than 100ms */
do {
ret = ioread16be(OCT_CONTROL_REG);
} while ((ret & (1<<8)) && time_before(jiffies, stop));
spin_unlock_irqrestore(&xb->lock, flags);
WARN_ON_ONCE(time_after_eq(jiffies, stop));
}
#ifdef HAVE_RATELIMIT
static DEFINE_RATELIMIT_STATE(_underrun_rl, DEFAULT_RATELIMIT_INTERVAL,
DEFAULT_RATELIMIT_BURST);
#endif
/* wcxb_reset_dring needs to be called with xb->lock held. */
static void _wcxb_reset_dring(struct wcxb *xb)
{
int x;
struct wcxb_meta_desc *mdesc;
struct wcxb_hw_desc *hdesc = NULL;
xb->dma_head = xb->dma_tail = 0;
if (unlikely(xb->latency > DRING_SIZE)) {
#ifdef HAVE_RATELIMIT
if (__ratelimit(&_underrun_rl)) {
#else
if (printk_ratelimit()) {
#endif
dev_info(&xb->pdev->dev,
"Oops! Tried to increase latency past buffer size.\n");
}
xb->latency = DRING_SIZE;
}
for (x = 0; x < xb->latency; x++) {
dma_addr_t dma_tmp;
mdesc = &xb->meta_dring[x];
hdesc = &xb->hw_dring[x];
hdesc->status = cpu_to_be32(DESC_DEFAULT_STATUS);
if (!mdesc->tx_buf_virt) {
mdesc->tx_buf_virt =
dma_pool_alloc(xb->pool, GFP_ATOMIC, &dma_tmp);
hdesc->tx_buf = cpu_to_be32(dma_tmp);
mdesc->rx_buf_virt =
dma_pool_alloc(xb->pool, GFP_ATOMIC, &dma_tmp);
hdesc->rx_buf = cpu_to_be32(dma_tmp);
}
hdesc->control = cpu_to_be32(DESC_INT|DESC_OWN);
BUG_ON(!mdesc->tx_buf_virt || !mdesc->rx_buf_virt);
}
BUG_ON(!hdesc);
/* Set end of ring bit in last descriptor to force hw to loop around */
hdesc->control |= cpu_to_be32(DESC_EOR);
iowrite32be(xb->hw_dring_phys, xb->membase + TDM_DRING_ADDR);
}
static void wcxb_handle_dma(struct wcxb *xb)
{
struct wcxb_meta_desc *mdesc;
while (!(xb->hw_dring[xb->dma_tail].control & cpu_to_be32(DESC_OWN))) {
u_char *frame;
mdesc = &xb->meta_dring[xb->dma_tail];
frame = mdesc->rx_buf_virt;
xb->ops->handle_receive(xb, frame);
xb->dma_tail =
(xb->dma_tail == xb->latency-1) ? 0 : xb->dma_tail + 1;
mdesc = &xb->meta_dring[xb->dma_head];
frame = mdesc->tx_buf_virt;
xb->ops->handle_transmit(xb, frame);
wmb();
xb->hw_dring[xb->dma_head].control |= cpu_to_be32(DESC_OWN);
xb->dma_head =
(xb->dma_head == xb->latency-1) ? 0 : xb->dma_head + 1;
}
}
static irqreturn_t _wcxb_isr(int irq, void *dev_id)
{
struct wcxb *xb = dev_id;
unsigned int limit = 8;
u32 pending;
pending = ioread32be(xb->membase + ISR);
if (!pending)
return IRQ_NONE;
do {
iowrite32be(pending, xb->membase + IAR);
if (pending & DESC_UNDERRUN) {
u32 reg;
/* bump latency */
spin_lock(&xb->lock);
if (!xb->flags.latency_locked) {
xb->latency++;
#ifdef HAVE_RATELIMIT
if (__ratelimit(&_underrun_rl)) {
#else
if (printk_ratelimit()) {
#endif
dev_info(&xb->pdev->dev,
"Underrun detected by hardware. Latency bumped to: %dms\n",
xb->latency);
}
}
/* re-setup dma ring */
_wcxb_reset_dring(xb);
/* set dma enable bit */
reg = ioread32be(xb->membase + TDM_CONTROL);
reg |= ENABLE_DMA;
iowrite32be(reg, xb->membase + TDM_CONTROL);
spin_unlock(&xb->lock);
}
if (pending & DESC_COMPLETE) {
xb->framecount++;
wcxb_handle_dma(xb);
}
if (NULL != xb->ops->handle_interrupt)
xb->ops->handle_interrupt(xb, pending);
pending = ioread32be(xb->membase + ISR);
} while (pending && --limit);
return IRQ_HANDLED;
}
DAHDI_IRQ_HANDLER(wcxb_isr)
{
irqreturn_t ret;
unsigned long flags;
local_irq_save(flags);
ret = _wcxb_isr(irq, dev_id);
local_irq_restore(flags);
return ret;
}
static int wcxb_alloc_dring(struct wcxb *xb, const char *board_name)
{
xb->meta_dring =
kzalloc(sizeof(struct wcxb_meta_desc) * DRING_SIZE,
GFP_KERNEL);
if (!xb->meta_dring)
return -ENOMEM;
xb->hw_dring = dma_alloc_coherent(&xb->pdev->dev,
sizeof(struct wcxb_hw_desc) * DRING_SIZE,
&xb->hw_dring_phys,
GFP_KERNEL);
if (!xb->hw_dring) {
kfree(xb->meta_dring);
return -ENOMEM;
}
xb->pool = dma_pool_create(board_name, &xb->pdev->dev,
PAGE_SIZE, PAGE_SIZE, 0);
if (!xb->pool) {
kfree(xb->meta_dring);
dma_free_coherent(&xb->pdev->dev,
sizeof(struct wcxb_hw_desc) * DRING_SIZE,
xb->hw_dring,
xb->hw_dring_phys);
return -ENOMEM;
}
return 0;
}
/**
* wcxb_soft_reset - Set interface registers back to known good values.
*
* This represents the normal default state after a reset of the FPGA. This
* function is preferred over the hard reset function.
*
*/
static void wcxb_soft_reset(struct wcxb *xb)
{
/* digium_gpo */
iowrite32be(0x0, xb->membase);
/* xps_intc */
iowrite32be(0x0, xb->membase + 0x300);
iowrite32be(0x0, xb->membase + 0x308);
iowrite32be(0x0, xb->membase + 0x310);
iowrite32be(0x0, xb->membase + 0x31C);
/* xps_spi_config_flash */
iowrite32be(0xA, xb->membase + 0x200);
/* tdm engine */
iowrite32be(0x0, xb->membase + 0x2000);
iowrite32be(0x0, xb->membase + 0x2004);
}
static void _wcxb_hard_reset(struct wcxb *xb)
{
struct pci_dev *const pdev = xb->pdev;
u32 microblaze_version;
unsigned long stop_time = jiffies + msecs_to_jiffies(2000);
pci_save_state(pdev);
iowrite32be(0xe00, xb->membase + TDM_CONTROL);
/* This sleep is to give FPGA time to bring up the PCI/PCIe interface */
msleep(200);
pci_restore_state(pdev);
/* Wait for the Microblaze CPU to complete it's startup */
do {
msleep(20);
/* Can return either 0xffff or 0 before it's fully booted */
microblaze_version = ioread32be(xb->membase + 0x2018) ?: 0xffff;
} while (time_before(jiffies, stop_time)
&& 0xffff == microblaze_version);
}
/*
* Since the FPGA hard reset drops the PCIe link we need to disable
* error reporting on the upsteam link. Otherwise Surprise Down errors
* may be reported in reponse to the link going away.
*
* NOTE: We cannot use pci_disable_pcie_error_reporting() because it will not
* disable error reporting if the system firmware is attached to the advanced
* error reporting mechanism.
*/
static void _wcxb_pcie_hard_reset(struct wcxb *xb)
{
struct pci_dev *const parent = xb->pdev->bus->self;
u32 aer_mask;
int pos;
if (!wcxb_is_pcie(xb))
return;
pos = pci_find_ext_capability(parent, PCI_EXT_CAP_ID_ERR);
if (pos) {
pci_read_config_dword(parent, pos + PCI_ERR_UNCOR_MASK,
&aer_mask);
pci_write_config_dword(parent, pos + PCI_ERR_UNCOR_MASK,
aer_mask | PCI_ERR_UNC_SURPDN);
}
_wcxb_hard_reset(xb);
if (pos) {
pci_write_config_dword(parent, pos + PCI_ERR_UNCOR_MASK,
aer_mask);
/* Clear the error as well from the status register. */
pci_write_config_dword(parent, pos + PCI_ERR_UNCOR_STATUS,
PCI_ERR_UNC_SURPDN);
}
return;
}
/**
* wcxb_hard_reset - Reset FPGA and reload firmware.
*
* This may be called in the context of device probe and therefore the PCI
* device may be locked.
*
*/
static void wcxb_hard_reset(struct wcxb *xb)
{
if (wcxb_is_pcie(xb))
_wcxb_pcie_hard_reset(xb);
else
_wcxb_hard_reset(xb);
}
int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode)
{
int res = 0;
struct pci_dev *pdev = xb->pdev;
u32 tdm_control;
if (pci_enable_device(pdev))
return -EIO;
pci_set_master(pdev);
#ifdef WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
xb->flags.is_pcie = pci_find_capability(pdev, PCI_CAP_ID_EXP) ? 1 : 0;
#endif
WARN_ON(!pdev);
if (!pdev)
return -EINVAL;
xb->latency = WCXB_DEFAULT_LATENCY;
spin_lock_init(&xb->lock);
xb->membase = pci_iomap(pdev, 0, 0);
if (pci_request_regions(pdev, board_name))
dev_info(&xb->pdev->dev, "Unable to request regions\n");
wcxb_soft_reset(xb);
res = wcxb_alloc_dring(xb, board_name);
if (res) {
dev_err(&xb->pdev->dev,
"Failed to allocate descriptor rings.\n");
goto fail_exit;
}
/* Enable writes to fpga status register */
iowrite32be(0, xb->membase + 0x04);
xb->flags.have_msi = (int_mode) ? 0 : (0 == pci_enable_msi(pdev));
if (request_irq(pdev->irq, wcxb_isr,
(xb->flags.have_msi) ? 0 : DAHDI_IRQ_SHARED,
board_name, xb)) {
dev_notice(&xb->pdev->dev, "Unable to request IRQ %d\n",
pdev->irq);
res = -EIO;
goto fail_exit;
}
iowrite32be(0, xb->membase + TDM_CONTROL);
tdm_control = ioread32be(xb->membase + TDM_CONTROL);
if (!(tdm_control & 0x20)) {
dev_err(&xb->pdev->dev,
"This board is not authenticated and may not function properly.\n");
msleep(1000);
} else {
dev_dbg(&xb->pdev->dev, "Authenticated. %08x\n", tdm_control);
}
return res;
fail_exit:
pci_release_regions(xb->pdev);
return res;
}
void wcxb_stop_dma(struct wcxb *xb)
{
unsigned long flags;
u32 reg;
/* Quiesce DMA engine interrupts */
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase + TDM_CONTROL);
reg &= ~ENABLE_DMA;
iowrite32be(reg, xb->membase + TDM_CONTROL);
spin_unlock_irqrestore(&xb->lock, flags);
}
int wcxb_wait_for_stop(struct wcxb *xb, unsigned long timeout_ms)
{
unsigned long stop;
stop = jiffies + msecs_to_jiffies(timeout_ms);
do {
if (time_after(jiffies, stop))
return -EIO;
else
cpu_relax();
} while (!wcxb_is_stopped(xb));
return 0;
}
void wcxb_disable_interrupts(struct wcxb *xb)
{
iowrite32be(0, xb->membase + IER);
}
void wcxb_stop(struct wcxb *xb)
{
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
/* Stop everything */
iowrite32be(0, xb->membase + TDM_CONTROL);
iowrite32be(0, xb->membase + IER);
iowrite32be(0, xb->membase + MER);
iowrite32be(-1, xb->membase + IAR);
/* Flush quiesce commands before exit */
ioread32be(xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
synchronize_irq(xb->pdev->irq);
}
bool wcxb_is_stopped(struct wcxb *xb)
{
return !(ioread32be(xb->membase + TDM_CONTROL) & DMA_RUNNING);
}
static void wcxb_free_dring(struct wcxb *xb)
{
struct wcxb_meta_desc *mdesc;
struct wcxb_hw_desc *hdesc;
int i;
/* Free tx/rx buffs */
for (i = 0; i < DRING_SIZE; i++) {
mdesc = &xb->meta_dring[i];
hdesc = &xb->hw_dring[i];
if (mdesc->tx_buf_virt) {
dma_pool_free(xb->pool,
mdesc->tx_buf_virt,
be32_to_cpu(hdesc->tx_buf));
dma_pool_free(xb->pool,
mdesc->rx_buf_virt,
be32_to_cpu(hdesc->rx_buf));
}
}
dma_pool_destroy(xb->pool);
dma_free_coherent(&xb->pdev->dev,
sizeof(struct wcxb_hw_desc) * DRING_SIZE,
xb->hw_dring,
xb->hw_dring_phys);
kfree(xb->meta_dring);
}
void wcxb_release(struct wcxb *xb)
{
wcxb_stop(xb);
synchronize_irq(xb->pdev->irq);
free_irq(xb->pdev->irq, xb);
if (xb->flags.have_msi)
pci_disable_msi(xb->pdev);
if (xb->membase)
pci_iounmap(xb->pdev, xb->membase);
wcxb_free_dring(xb);
pci_release_regions(xb->pdev);
pci_disable_device(xb->pdev);
return;
}
int wcxb_start(struct wcxb *xb)
{
u32 reg;
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
_wcxb_reset_dring(xb);
/* Enable hardware interrupts */
iowrite32be(-1, xb->membase + IAR);
iowrite32be(DESC_UNDERRUN|DESC_COMPLETE, xb->membase + IER);
/* iowrite32be(0x3f7, xb->membase + IER); */
iowrite32be(MER_ME|MER_HIE, xb->membase + MER);
/* Start the DMA engine processing. */
reg = ioread32be(xb->membase + TDM_CONTROL);
reg |= ENABLE_DMA;
iowrite32be(reg, xb->membase + TDM_CONTROL);
spin_unlock_irqrestore(&xb->lock, flags);
return 0;
}
struct wcxb_meta_block {
__le32 chksum;
__le32 version;
__le32 size;
} __packed;
struct wcxb_firm_header {
u8 header[6];
__le32 chksum;
u8 pad[18];
__le32 version;
} __packed;
static u32 wcxb_get_firmware_version(struct wcxb *xb)
{
u32 version = 0;
/* Two version registers are read and catenated into one */
/* Firmware version goes in bits upper byte */
version = ((ioread32be(xb->membase + 0x400) & 0xffff)<<16);
/* Microblaze version goes in lower word */
version += ioread32be(xb->membase + 0x2018);
return version;
}
static int wcxb_update_firmware(struct wcxb *xb, const struct firmware *fw,
const char *filename)
{
u32 tdm_control;
static const int APPLICATION_ADDRESS = 0x200000;
static const int META_BLOCK_OFFSET = 0x170000;
static const int ERASE_BLOCK_SIZE = 0x010000;
static const int END_OFFSET = APPLICATION_ADDRESS + META_BLOCK_OFFSET +
ERASE_BLOCK_SIZE;
struct wcxb_spi_master *flash_spi_master;
struct wcxb_spi_device *flash_spi_device;
struct wcxb_meta_block meta;
int offset;
struct wcxb_firm_header *head = (struct wcxb_firm_header *)(fw->data);
if (fw->size > (META_BLOCK_OFFSET + sizeof(*head))) {
dev_err(&xb->pdev->dev,
"Firmware is too large to fit in available space.\n");
return -EINVAL;
}
meta.size = cpu_to_le32(fw->size);
meta.version = head->version;
meta.chksum = head->chksum;
flash_spi_master = wcxb_spi_master_create(&xb->pdev->dev,
xb->membase + FLASH_SPI_BASE,
false);
flash_spi_device = wcxb_spi_device_create(flash_spi_master, 0);
dev_info(&xb->pdev->dev,
"Uploading %s. This can take up to 30 seconds.\n", filename);
/* First erase all the blocks in the application area. */
offset = APPLICATION_ADDRESS;
while (offset < END_OFFSET) {
wcxb_flash_sector_erase(flash_spi_device, offset);
offset += ERASE_BLOCK_SIZE;
}
/* Then write the new firmware file. */
wcxb_flash_write(flash_spi_device, APPLICATION_ADDRESS,
&fw->data[sizeof(struct wcxb_firm_header)],
fw->size - sizeof(struct wcxb_firm_header));
/* Finally, update the meta block. */
wcxb_flash_write(flash_spi_device,
APPLICATION_ADDRESS + META_BLOCK_OFFSET,
&meta, sizeof(meta));
/* Reset fpga after loading firmware */
dev_info(&xb->pdev->dev, "Firmware load complete. Reseting device.\n");
tdm_control = ioread32be(xb->membase + TDM_CONTROL);
wcxb_hard_reset(xb);
iowrite32be(0, xb->membase + 0x04);
iowrite32be(tdm_control, xb->membase + TDM_CONTROL);
wcxb_spi_device_destroy(flash_spi_device);
wcxb_spi_master_destroy(flash_spi_master);
return 0;
}
int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
const char *firmware_filename, bool force_firmware)
{
const struct firmware *fw;
const struct wcxb_firm_header *header;
int res = 0;
u32 crc;
u32 version = 0;
version = wcxb_get_firmware_version(xb);
if (0xff000000 == (version & 0xff000000)) {
dev_info(&xb->pdev->dev,
"Invalid firmware %x. Please check your hardware.\n",
version);
return -EIO;
}
if ((expected_version == version) && !force_firmware) {
dev_info(&xb->pdev->dev, "Firmware version: %x\n", version);
return 0;
}
if (force_firmware) {
dev_info(&xb->pdev->dev,
"force_firmware module parameter is set. Forcing firmware load, regardless of version\n");
} else {
dev_info(&xb->pdev->dev,
"Firmware version %x is running, but we require version %x.\n",
version, expected_version);
}
res = request_firmware(&fw, firmware_filename, &xb->pdev->dev);
if (res) {
dev_info(&xb->pdev->dev,
"Firmware '%s' not available from userspace.\n",
firmware_filename);
goto cleanup;
}
header = (const struct wcxb_firm_header *)fw->data;
/* Check the crc */
crc = crc32(~0, &fw->data[10], fw->size - 10) ^ ~0;
if (memcmp("DIGIUM", header->header, sizeof(header->header)) ||
(le32_to_cpu(header->chksum) != crc)) {
dev_info(&xb->pdev->dev,
"%s is invalid. Please reinstall.\n",
firmware_filename);
goto cleanup;
}
/* Check the file vs required firmware versions */
if (le32_to_cpu(header->version) != expected_version) {
dev_err(&xb->pdev->dev,
"Existing firmware file %s is version %x, but we require %x. Please install the correct firmware file.\n",
firmware_filename, le32_to_cpu(header->version),
expected_version);
res = -EIO;
goto cleanup;
}
dev_info(&xb->pdev->dev, "Found %s (version: %x) Preparing for flash\n",
firmware_filename, header->version);
res = wcxb_update_firmware(xb, fw, firmware_filename);
version = wcxb_get_firmware_version(xb);
dev_info(&xb->pdev->dev, "Reset into firmware version: %x\n", version);
if ((expected_version != version) && !force_firmware) {
/* On the off chance that the interface is in a state where it
* cannot boot into the updated firmware image, power cycling
* the card can recover. A simple "reset" of the computer is not
* sufficient, power has to be removed completely. */
dev_err(&xb->pdev->dev,
"The wrong firmware is running after update. Please power cycle and try again.\n");
res = -EIO;
goto cleanup;
}
if (res) {
dev_info(&xb->pdev->dev,
"Failed to load firmware %s\n", firmware_filename);
}
cleanup:
release_firmware(fw);
return res;
}

View File

@@ -1,184 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#ifndef __WCXB_H__
#define __WCXB_H__
#define WCXB_DEFAULT_LATENCY 3U
#define WCXB_DEFAULT_MAXLATENCY 20U
#define WCXB_DMA_CHAN_SIZE 128
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
/* The is_pcie member was backported but I'm not sure in which version. */
# ifndef RHEL_RELEASE_VERSION
#define WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
# endif
#else
#endif
struct wcxb;
struct wcxb_operations {
void (*handle_receive)(struct wcxb *xb, void *frame);
void (*handle_transmit)(struct wcxb *xb, void *frame);
void (*handle_error)(struct wcxb *xb);
void (*handle_interrupt)(struct wcxb *xb, u32 pending);
};
struct wcxb_meta_desc;
struct wcxb_hw_desc;
struct wcxb {
struct pci_dev *pdev;
spinlock_t lock;
const struct wcxb_operations *ops;
unsigned int *debug;
unsigned int max_latency;
unsigned int latency;
struct {
u32 have_msi:1;
u32 latency_locked:1;
u32 drive_timing_cable:1;
#ifdef WCXB_PCI_DEV_DOES_NOT_HAVE_IS_PCIE
u32 is_pcie:1;
#endif
} flags;
void __iomem *membase;
struct wcxb_meta_desc *meta_dring;
struct wcxb_hw_desc *hw_dring;
unsigned int dma_head;
unsigned int dma_tail;
dma_addr_t hw_dring_phys;
struct dma_pool *pool;
unsigned long framecount;
};
extern int wcxb_init(struct wcxb *xb, const char *board_name, u32 int_mode);
extern void wcxb_release(struct wcxb *xb);
extern int wcxb_start(struct wcxb *xb);
extern void wcxb_stop(struct wcxb *xb);
extern int wcxb_wait_for_stop(struct wcxb *xb, unsigned long timeout_ms);
extern bool wcxb_is_stopped(struct wcxb *xb);
enum wcxb_clock_sources {
WCXB_CLOCK_SELF, /* Use the internal oscillator for timing. */
WCXB_CLOCK_RECOVER, /* Recover the clock from a framer. */
#ifdef RPC_RCLK
WCXB_CLOCK_RECOVER_ALT, /* Recover the clock from a framer. */
#endif
WCXB_CLOCK_SLAVE /* Recover clock from any timing header. */
};
extern enum wcxb_clock_sources wcxb_get_clksrc(struct wcxb *xb);
extern void wcxb_set_clksrc(struct wcxb *xb, enum wcxb_clock_sources clksrc);
static inline void wcxb_enable_timing_header_driver(struct wcxb *xb)
{
xb->flags.drive_timing_cable = 1;
}
static inline bool wcxb_is_timing_header_driver_enabled(struct wcxb *xb)
{
return 1 == xb->flags.drive_timing_cable;
}
static inline void wcxb_disable_timing_header_driver(struct wcxb *xb)
{
xb->flags.drive_timing_cable = 0;
}
extern int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
const char *firmware_filename,
bool force_firmware);
extern void wcxb_stop_dma(struct wcxb *xb);
extern void wcxb_disable_interrupts(struct wcxb *xb);
static inline void wcxb_gpio_set(struct wcxb *xb, u32 bits)
{
u32 reg;
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase);
iowrite32be(reg | bits, xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
}
static inline void wcxb_gpio_clear(struct wcxb *xb, u32 bits)
{
u32 reg;
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
reg = ioread32be(xb->membase);
iowrite32be(reg & (~bits), xb->membase);
spin_unlock_irqrestore(&xb->lock, flags);
}
static inline void
wcxb_set_maxlatency(struct wcxb *xb, unsigned int max_latency)
{
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
xb->max_latency = clamp(max_latency,
xb->latency,
WCXB_DEFAULT_MAXLATENCY);
spin_unlock_irqrestore(&xb->lock, flags);
}
static inline void
wcxb_set_minlatency(struct wcxb *xb, unsigned int min_latency)
{
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
xb->latency = clamp(min_latency, WCXB_DEFAULT_LATENCY,
WCXB_DEFAULT_MAXLATENCY);
spin_unlock_irqrestore(&xb->lock, flags);
}
static inline void
wcxb_lock_latency(struct wcxb *xb)
{
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
xb->flags.latency_locked = 1;
spin_unlock_irqrestore(&xb->lock, flags);
return;
}
static inline void
wcxb_unlock_latency(struct wcxb *xb)
{
unsigned long flags;
spin_lock_irqsave(&xb->lock, flags);
xb->flags.latency_locked = 0;
spin_unlock_irqrestore(&xb->lock, flags);
return;
}
/* Interface for the echocan block */
extern void wcxb_enable_echocan(struct wcxb *xb);
extern void wcxb_disable_echocan(struct wcxb *xb);
extern void wcxb_reset_echocan(struct wcxb *xb);
extern void wcxb_enable_echocan_dram(struct wcxb *xb);
extern bool wcxb_is_echocan_present(struct wcxb *xb);
extern u16 wcxb_get_echocan_reg(struct wcxb *xb, u32 address);
extern void wcxb_set_echocan_reg(struct wcxb *xb, u32 address, u16 val);
#endif

View File

@@ -1,170 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/sched.h>
#include "wcxb_spi.h"
#include "wcxb_flash.h"
#define FLASH_PAGE_PROGRAM 0x02
#define FLASH_READ 0x03
#define FLASH_READ_STATUS 0x05
#define FLASH_WRITE_ENABLE 0x06
#define FLASH_SECTOR_ERASE 0xd8
static int wcxb_flash_read_status_register(struct wcxb_spi_device *spi,
u8 *status)
{
u8 command[] = {
FLASH_READ_STATUS,
};
struct wcxb_spi_transfer t_cmd = {
.tx_buf = command,
.len = sizeof(command),
};
struct wcxb_spi_transfer t_serial = {
.rx_buf = status,
.len = 1,
};
struct wcxb_spi_message m;
wcxb_spi_message_init(&m);
wcxb_spi_message_add_tail(&t_cmd, &m);
wcxb_spi_message_add_tail(&t_serial, &m);
return wcxb_spi_sync(spi, &m);
}
int wcxb_flash_read(struct wcxb_spi_device *spi, unsigned int address,
void *data, size_t len)
{
u8 command[] = {
FLASH_READ,
(address & 0xff0000) >> 16,
(address & 0xff00) >> 8,
(address & 0xff)
};
struct wcxb_spi_transfer t_cmd = {
.tx_buf = command,
.len = sizeof(command),
};
struct wcxb_spi_transfer t_serial = {
.rx_buf = data,
.len = len,
};
struct wcxb_spi_message m;
wcxb_spi_message_init(&m);
wcxb_spi_message_add_tail(&t_cmd, &m);
wcxb_spi_message_add_tail(&t_serial, &m);
return wcxb_spi_sync(spi, &m);
}
static int wcxb_flash_wait_until_not_busy(struct wcxb_spi_device *spi)
{
int res;
u8 status;
unsigned long stop = jiffies + 5*HZ;
do {
res = wcxb_flash_read_status_register(spi, &status);
} while (!res && (status & 0x1) && time_before(jiffies, stop));
if (!res)
return res;
if (time_after_eq(jiffies, stop))
return -EIO;
return 0;
}
static int wcxb_flash_write_enable(struct wcxb_spi_device *spi)
{
u8 command = FLASH_WRITE_ENABLE;
return wcxb_spi_write(spi, &command, 1);
}
int wcxb_flash_sector_erase(struct wcxb_spi_device *spi,
unsigned int address)
{
int res;
u8 command[] = {FLASH_SECTOR_ERASE, (address >> 16)&0xff, 0x00, 0x00};
/* Sector must be on 64KB boundary. */
if (address & 0xffff)
return -EINVAL;
/* Start the erase. */
res = wcxb_flash_write_enable(spi);
if (res)
return res;
res = wcxb_spi_write(spi, &command, sizeof(command));
if (res)
return res;
return wcxb_flash_wait_until_not_busy(spi);
}
int wcxb_flash_write(struct wcxb_spi_device *spi, unsigned int address,
const void *data, size_t len)
{
int res;
const size_t FLASH_PAGE_SIZE = 256;
u8 command[] = {
FLASH_PAGE_PROGRAM,
(address & 0xff0000) >> 16,
(address & 0xff00) >> 8,
0x00,
};
struct wcxb_spi_transfer t_cmd = {
.tx_buf = command,
.len = sizeof(command),
};
struct wcxb_spi_transfer t_data = {
.tx_buf = data,
.len = len,
};
struct wcxb_spi_message m;
/* We need to write on page size boundaries */
WARN_ON(address & 0xff);
wcxb_spi_message_init(&m);
wcxb_spi_message_add_tail(&t_cmd, &m);
wcxb_spi_message_add_tail(&t_data, &m);
while (len) {
res = wcxb_flash_write_enable(spi);
if (res)
return res;
command[1] = (address >> 16) & 0xff;
command[2] = (address >> 8) & 0xff;
t_data.tx_buf = data;
t_data.len = min(len, FLASH_PAGE_SIZE);
res = wcxb_spi_sync(spi, &m);
WARN_ON(res);
if (res)
return res;
res = wcxb_flash_wait_until_not_busy(spi);
WARN_ON(res);
if (res)
return res;
len -= t_data.len;
address += t_data.len;
data += t_data.len;
}
return 0;
}

View File

@@ -1,34 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#ifndef __WCXB_FLASH_H__
#define __WCXB_FLASH_H__
extern int wcxb_flash_read(struct wcxb_spi_device *spi, unsigned int address,
void *data, size_t len);
extern int wcxb_flash_sector_erase(struct wcxb_spi_device *spi, unsigned int
address);
extern int wcxb_flash_write(struct wcxb_spi_device *spi, unsigned int address,
const void *data, size_t len);
#endif

View File

@@ -1,386 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#define DEBUG
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/completion.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <dahdi/kernel.h>
#include "wcxb_spi.h"
#define BBIT(n) (1UL << (31UL - (n)))
#define SPISRR 0x40
#define SPISRR_RESET 0x0000000a /* Resets Device */
#define SPICR 0x60
#define SPICR_LSB_FIRST BBIT(22) /* LSB First. 0=MSB first transfer */
#define SPICR_MASTER_INHIBIT BBIT(23) /* Master Transaction Inhibit */
#define SPICR_SLAVE_SELECT BBIT(24) /* Manual Slave Select Assert Enable */
#define SPICR_RX_FIFO_RESET BBIT(25) /* Receive FIFO Reset */
#define SPICR_TX_FIFO_RESET BBIT(26) /* Transmit FIFO Reset */
#define SPICR_CPHA BBIT(27) /* Clock Phase */
#define SPICR_CPOL BBIT(28) /* Clock Polarity 0=Active High */
#define SPICR_MASTER BBIT(29) /* Master Enable */
#define SPICR_SPE BBIT(30) /* SPI System Enable */
#define SPICR_LOOP BBIT(31) /* Local Loopback Mode */
#define SPICR_START_TRANSFER (SPICR_CPHA | SPICR_CPOL | \
SPICR_MASTER | SPICR_SPE)
#define SPICR_READY_TRANSFER (SPICR_MASTER_INHIBIT | SPICR_START_TRANSFER)
#define SPISR 0x64 /* SPI Status Register */
#define SPISR_SLAVE_MODE_SEL BBIT(26) /* Slave Mode Select Flag */
#define SPISR_MODF BBIT(27) /* Mode-Fault Error Flag */
#define SPISR_TX_FULL BBIT(28) /* Transmit FIFO Full */
#define SPISR_TX_EMPTY BBIT(29) /* Transmit FIFO Empty */
#define SPISR_RX_FULL BBIT(30) /* Receive FIFO Full */
#define SPISR_RX_EMPTY BBIT(31) /* Receive FIFO Empty */
#define SPIDTR 0x68 /* SPI Data Transmit Register */
#define SPIDRR 0x6c /* SPI Data Receive Register */
#define SPISSR 0x70 /* SPI Slave Select Register */
#undef SUCCESS
#define SUCCESS 0
struct wcxb_spi_master {
struct device *parent;
struct list_head message_queue;
spinlock_t lock;
void __iomem *base;
struct wcxb_spi_message *cur_msg;
struct wcxb_spi_transfer *cur_transfer;
u16 bytes_left;
u16 bytes_in_fifo;
const u8 *cur_tx_byte;
u8 *cur_rx_byte;
u16 auto_cs:1;
};
static inline void _wcxb_assert_chip_select(struct wcxb_spi_master *master,
unsigned int cs)
{
const int cs_mask = ~(1UL << cs);
iowrite32be(cs_mask, master->base + SPISSR);
ioread32be(master->base + SPISSR);
}
static inline void _wcxb_clear_chip_select(struct wcxb_spi_master *master)
{
iowrite32be(~(0), master->base + SPISSR);
ioread32(master->base + SPISSR);
}
static inline void wcxb_spi_reset_controller(struct wcxb_spi_master *master)
{
u32 spicr = SPICR_READY_TRANSFER;
spicr |= (master->auto_cs) ? 0 : SPICR_SLAVE_SELECT;
iowrite32be(SPISRR_RESET, master->base + SPISRR);
iowrite32be(spicr, master->base + SPICR);
iowrite32be(0xffffffff, master->base + SPISSR);
}
struct wcxb_spi_master *wcxb_spi_master_create(struct device *parent,
void __iomem *membase,
bool auto_cs)
{
struct wcxb_spi_master *master = NULL;
master = kzalloc(sizeof(struct wcxb_spi_master), GFP_KERNEL);
if (!master)
goto error_exit;
spin_lock_init(&master->lock);
INIT_LIST_HEAD(&master->message_queue);
master->base = membase;
master->parent = parent;
master->auto_cs = (auto_cs) ? 1 : 0;
wcxb_spi_reset_controller(master);
return master;
error_exit:
kfree(master);
return NULL;
}
void wcxb_spi_master_destroy(struct wcxb_spi_master *master)
{
struct wcxb_spi_message *m;
if (!master)
return;
while (!list_empty(&master->message_queue)) {
m = list_first_entry(&master->message_queue,
struct wcxb_spi_message, node);
list_del(&m->node);
if (m->complete)
m->complete(m->arg);
}
kfree(master);
return;
}
static inline bool is_txfifo_empty(const struct wcxb_spi_master *master)
{
return ((ioread32(master->base + SPISR) &
cpu_to_be32(SPISR_TX_EMPTY)) > 0);
}
static const u8 DUMMY_TX = 0xff;
static u8 DUMMY_RX;
static void _wcxb_spi_transfer_to_fifo(struct wcxb_spi_master *master)
{
const unsigned int FIFO_SIZE = 16;
u32 spicr;
while (master->bytes_left && master->bytes_in_fifo < FIFO_SIZE) {
iowrite32be(*master->cur_tx_byte, master->base + SPIDTR);
master->bytes_in_fifo++;
master->bytes_left--;
if (&DUMMY_TX != master->cur_tx_byte)
master->cur_tx_byte++;
}
spicr = (master->auto_cs) ? SPICR_START_TRANSFER :
SPICR_START_TRANSFER | SPICR_SLAVE_SELECT;
iowrite32be(spicr, master->base + SPICR);
}
static void _wcxb_spi_transfer_from_fifo(struct wcxb_spi_master *master)
{
u32 spicr;
while (master->bytes_in_fifo) {
*master->cur_rx_byte = ioread32be(master->base + SPIDRR);
if (&DUMMY_RX != master->cur_rx_byte)
master->cur_rx_byte++;
--master->bytes_in_fifo;
}
spicr = SPICR_START_TRANSFER;
spicr |= (master->auto_cs) ? 0 : SPICR_SLAVE_SELECT;
iowrite32be(spicr | SPICR_MASTER_INHIBIT, master->base + SPICR);
}
static void _wcxb_spi_start_transfer(struct wcxb_spi_master *master,
struct wcxb_spi_transfer *t)
{
#ifdef DEBUG
if (!t || !master || (!t->tx_buf && !t->rx_buf) ||
master->cur_transfer) {
WARN_ON(1);
return;
}
#endif
master->cur_transfer = t;
master->bytes_left = t->len;
master->cur_tx_byte = (t->tx_buf) ?: &DUMMY_TX;
master->cur_rx_byte = (t->rx_buf) ?: &DUMMY_RX;
_wcxb_spi_transfer_to_fifo(master);
}
/**
* _wcxb_spi_start_message - Start a new message transferring.
*
* Must be called with master->lock held.
*
*/
static int _wcxb_spi_start_message(struct wcxb_spi_master *master,
struct wcxb_spi_message *message)
{
struct wcxb_spi_transfer *t;
if (master->cur_msg) {
/* There is already a message in progress. Queue for later. */
list_add_tail(&message->node, &master->message_queue);
return 0;
}
if (!message->spi) {
dev_dbg(master->parent,
"Queueing message without SPI device specified?\n");
return -EINVAL;
};
master->cur_msg = message;
_wcxb_assert_chip_select(master, message->spi->chip_select);
t = list_first_entry(&message->transfers,
struct wcxb_spi_transfer, node);
_wcxb_spi_start_transfer(master, t);
return 0;
}
/**
* wcxb_spi_complete_message - Complete the current message.
*
* Called after all transfers in current message have been completed. This will
* complete the current message and start the next queued message if there are
* any.
*
* Must be called with the master->lock held.
*
*/
static void _wcxb_spi_complete_cur_msg(struct wcxb_spi_master *master)
{
struct wcxb_spi_message *message;
if (!master->cur_msg)
return;
message = master->cur_msg;
message->status = SUCCESS;
_wcxb_clear_chip_select(master);
master->cur_msg = NULL;
if (!list_empty(&master->message_queue)) {
message = list_first_entry(&master->message_queue,
struct wcxb_spi_message, node);
list_del(&message->node);
_wcxb_spi_start_message(master, message);
}
return;
}
static inline bool
_wcxb_spi_is_last_transfer(const struct wcxb_spi_transfer *t,
const struct wcxb_spi_message *message)
{
return t->node.next == &message->transfers;
}
static inline struct wcxb_spi_transfer *
_wcxb_spi_next_transfer(struct wcxb_spi_transfer *t)
{
return list_entry(t->node.next, struct wcxb_spi_transfer, node);
}
/**
* wcxb_spi_handle_interrupt - Drives the transfers forward.
*
* Doesn't necessarily need to be called in the context of a real interrupt, but
* should be called with interrupts disabled on the local CPU.
*
*/
void wcxb_spi_handle_interrupt(struct wcxb_spi_master *master)
{
struct wcxb_spi_message *msg;
struct wcxb_spi_transfer *t;
void (*complete)(void *arg) = NULL;
unsigned long flags;
/* Check if we're not in the middle of a transfer, or not finished with
* a part of one. */
spin_lock_irqsave(&master->lock, flags);
t = master->cur_transfer;
msg = master->cur_msg;
if (!msg || !is_txfifo_empty(master))
goto done;
#ifdef DEBUG
if (!t) {
dev_dbg(master->parent,
"No current transfer in %s\n", __func__);
goto done;
}
#endif
/* First read any data out of the receive FIFO into the current
* transfer. */
_wcxb_spi_transfer_from_fifo(master);
if (master->bytes_left) {
/* The current transfer isn't finished. */
_wcxb_spi_transfer_to_fifo(master);
goto done;
}
/* The current transfer is finished. Check for another transfer in this
* message or complete it and look for another message to start. */
master->cur_transfer = NULL;
if (_wcxb_spi_is_last_transfer(t, msg)) {
complete = msg->complete;
_wcxb_spi_complete_cur_msg(master);
} else {
t = _wcxb_spi_next_transfer(t);
_wcxb_spi_start_transfer(master, t);
}
done:
spin_unlock_irqrestore(&master->lock, flags);
/* Do not call the complete call back under the bus lock. */
if (complete)
complete(msg->arg);
return;
}
int wcxb_spi_async(struct wcxb_spi_device *spi,
struct wcxb_spi_message *message)
{
int res;
unsigned long flags;
WARN_ON(!spi || !message || !spi->master);
if (list_empty(&message->transfers)) {
/* No transfers in this message? */
if (message->complete)
message->complete(message->arg);
message->status = -EINVAL;
return 0;
}
message->status = -EINPROGRESS;
message->spi = spi;
spin_lock_irqsave(&spi->master->lock, flags);
res = _wcxb_spi_start_message(spi->master, message);
spin_unlock_irqrestore(&spi->master->lock, flags);
return res;
}
static void wcxb_spi_complete_message(void *arg)
{
complete((struct completion *)arg);
}
int wcxb_spi_sync(struct wcxb_spi_device *spi, struct wcxb_spi_message *message)
{
DECLARE_COMPLETION_ONSTACK(done);
WARN_ON(!spi || !spi->master);
message->complete = wcxb_spi_complete_message;
message->arg = &done;
wcxb_spi_async(spi, message);
/* TODO: There has got to be a better way to do this. */
while (!try_wait_for_completion(&done)) {
wcxb_spi_handle_interrupt(spi->master);
cpu_relax();
}
return message->status;
}

View File

@@ -1,116 +0,0 @@
/*
* wcxb SPI library
*
* Copyright (C) 2013 Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#ifndef __WCXB_SPI_H
#define __WCXB_SPI_H
#include <linux/spi/spi.h>
#include <stdbool.h>
struct wcxb_spi_transfer {
const void *tx_buf;
void *rx_buf;
u32 len:16;
u16 delay_usecs;
struct list_head node;
};
struct wcxb_spi_message {
struct list_head transfers;
struct list_head node;
struct wcxb_spi_device *spi;
void (*complete)(void *arg);
void *arg;
int status;
};
struct wcxb_spi_master;
struct wcxb_spi_device {
struct wcxb_spi_master *master;
u16 chip_select;
};
extern struct wcxb_spi_master *wcxb_spi_master_create(struct device *parent,
void __iomem *base, bool auto_cs);
extern void wcxb_spi_master_destroy(struct wcxb_spi_master *master);
extern int wcxb_spi_sync(struct wcxb_spi_device *spi,
struct wcxb_spi_message *message);
extern int wcxb_spi_async(struct wcxb_spi_device *spi,
struct wcxb_spi_message *message);
extern void wcxb_spi_handle_interrupt(struct wcxb_spi_master *master);
static inline struct wcxb_spi_device *
wcxb_spi_device_create(struct wcxb_spi_master *master, u16 chip_select)
{
struct wcxb_spi_device *spi = kzalloc(sizeof(*spi), GFP_KERNEL);
if (!spi)
return NULL;
spi->master = master;
spi->chip_select = chip_select;
return spi;
}
static inline void wcxb_spi_device_destroy(struct wcxb_spi_device *spi)
{
kfree(spi);
}
static inline void wcxb_spi_message_init(struct wcxb_spi_message *m)
{
memset(m, 0, sizeof(*m));
INIT_LIST_HEAD(&m->transfers);
}
static inline void wcxb_spi_message_add_tail(struct wcxb_spi_transfer *t,
struct wcxb_spi_message *m)
{
list_add_tail(&t->node, &m->transfers);
}
static inline int
wcxb_spi_write(struct wcxb_spi_device *spi, const void *buffer, size_t len)
{
struct wcxb_spi_transfer t = {
.tx_buf = buffer,
.len = len,
};
struct wcxb_spi_message m;
wcxb_spi_message_init(&m);
wcxb_spi_message_add_tail(&t, &m);
return wcxb_spi_sync(spi, &m);
}
static inline int
wcxb_spi_read(struct wcxb_spi_device *spi, void *buffer, size_t len)
{
struct wcxb_spi_transfer t = {
.rx_buf = buffer,
.len = len,
};
struct wcxb_spi_message m;
wcxb_spi_message_init(&m);
wcxb_spi_message_add_tail(&t, &m);
return wcxb_spi_sync(spi, &m);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@
#include "xpd.h"
enum bri_opcodes {
XPROTO_NAME(BRI, SET_LED) = 0x33,
XPROTO_NAME(BRI, SET_LED) = 0x33,
};
#endif /* CARD_BRI_H */
#endif /* CARD_BRI_H */

View File

@@ -42,20 +42,25 @@ static DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
static bool echo_packet_is_valid(xpacket_t *pack);
static void echo_packet_dump(const char *msg, xpacket_t *pack);
DEF_RPACKET_DATA(ECHO, SET, __u8 timeslots[ECHO_TIMESLOTS];);
DEF_RPACKET_DATA(ECHO, SET,
byte timeslots[ECHO_TIMESLOTS];
);
DEF_RPACKET_DATA(ECHO, SET_REPLY, __u8 status; __u8 reserved;);
DEF_RPACKET_DATA(ECHO, SET_REPLY,
byte status;
byte reserved;
);
struct ECHO_priv_data {
};
static xproto_table_t PROTO_TABLE(ECHO);
static xproto_table_t PROTO_TABLE(ECHO);
/*---------------- ECHO: Methods -------------------------------------------*/
static xpd_t *ECHO_card_new(xbus_t *xbus, int unit, int subunit,
const xproto_table_t *proto_table, __u8 subtype,
int subunits, int subunit_ports, bool to_phone)
const xproto_table_t *proto_table, byte subtype,
int subunits, int subunit_ports, bool to_phone)
{
xpd_t *xpd = NULL;
int channels = 0;
@@ -65,9 +70,8 @@ static xpd_t *ECHO_card_new(xbus_t *xbus, int unit, int subunit,
return NULL;
}
XBUS_DBG(GENERAL, xbus, "\n");
xpd =
xpd_alloc(xbus, unit, subunit, subtype, subunits,
sizeof(struct ECHO_priv_data), proto_table, channels);
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits,
sizeof(struct ECHO_priv_data), proto_table, channels);
if (!xpd)
return NULL;
xpd->type_name = "ECHO";
@@ -118,17 +122,19 @@ static int ECHO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
static int rate_limit;
if ((rate_limit++ % 1003) < 5)
notify_bad_xpd(__func__, xbus, addr, orig_xpd->xpdname);
notify_bad_xpd(__func__, xbus, addr,
orig_xpd->xpdname);
return -EPROTO;
}
spin_lock_irqsave(&xpd->lock, flags);
/* Update /proc info only if reply related to last reg read request */
if (REG_FIELD(&xpd->requested_reply, regnum) ==
REG_FIELD(info, regnum)
&& REG_FIELD(&xpd->requested_reply, do_subreg) ==
REG_FIELD(info, do_subreg)
&& REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
if (
REG_FIELD(&xpd->requested_reply, regnum) ==
REG_FIELD(info, regnum) &&
REG_FIELD(&xpd->requested_reply, do_subreg) ==
REG_FIELD(info, do_subreg) &&
REG_FIELD(&xpd->requested_reply, subreg) ==
REG_FIELD(info, subreg)) {
xpd->last_reply = *info;
}
spin_unlock_irqrestore(&xpd->lock, flags);
@@ -140,7 +146,7 @@ static int ECHO_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
static /* 0x39 */ HOSTCMD(ECHO, SET)
{
struct xbus_echo_state *es;
__u8 *ts;
byte *ts;
xframe_t *xframe;
xpacket_t *pack;
int ret;
@@ -166,7 +172,7 @@ static int ECHO_ec_set(xpd_t *xpd, int pos, bool on)
{
int ts_number;
int ts_mask;
__u8 *ts;
byte *ts;
ts = xpd->xbus->echo_state.timeslots;
/*
@@ -192,7 +198,7 @@ static int ECHO_ec_set(xpd_t *xpd, int pos, bool on)
ts[ts_number] &= ~ts_mask;
}
LINE_DBG(GENERAL, xpd, pos, "%s = %d -- ts_number=%d ts_mask=0x%X\n",
__func__, on, ts_number, ts_mask);
__func__, on, ts_number, ts_mask);
return 0;
}
@@ -201,7 +207,7 @@ static int ECHO_ec_get(xpd_t *xpd, int pos)
int ts_number;
int ts_mask;
int is_on;
__u8 *ts;
byte *ts;
ts = xpd->xbus->echo_state.timeslots;
ts_mask = (xpd->addr.unit == 0) ? 0x1 : 0x2; /* Which bit? */
@@ -214,14 +220,14 @@ static int ECHO_ec_get(xpd_t *xpd, int pos)
}
#if 0
LINE_DBG(GENERAL, xpd, pos, "ec_get=%d -- ts_number=%d ts_mask=0x%X\n",
is_on, ts_number, ts_mask);
is_on, ts_number, ts_mask);
#endif
return is_on;
}
static void ECHO_ec_dump(xbus_t *xbus)
{
__u8 *ts;
byte *ts;
int i;
ts = xbus->echo_state.timeslots;
@@ -230,11 +236,12 @@ static void ECHO_ec_dump(xbus_t *xbus)
"EC-DUMP[%03d]: "
"0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X "
"0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n",
i, ts[i + 0], ts[i + 1], ts[i + 2], ts[i + 3],
ts[i + 4], ts[i + 5], ts[i + 6], ts[i + 7], ts[i + 8],
ts[i + 9], ts[i + 10], ts[i + 11], ts[i + 12],
ts[i + 13], ts[i + 14], ts[i + 15]
);
i,
ts[i+0], ts[i+1], ts[i+2], ts[i+3], ts[i+4], ts[i+5],
ts[i+6], ts[i+7],
ts[i+8], ts[i+9], ts[i+10], ts[i+11], ts[i+12],
ts[i+13], ts[i+14], ts[i+15]
);
}
}
@@ -248,7 +255,7 @@ static int ECHO_ec_update(xbus_t *xbus)
/*---------------- ECHO: Astribank Reply Handlers --------------------------*/
HANDLER_DEF(ECHO, SET_REPLY)
{
__u8 status;
byte status;
BUG_ON(!xpd);
status = RPACKET_FIELD(pack, ECHO, SET_REPLY, status);
@@ -256,26 +263,26 @@ HANDLER_DEF(ECHO, SET_REPLY)
return 0;
}
static const struct xops echo_xops = {
.card_new = ECHO_card_new,
.card_init = ECHO_card_init,
.card_remove = ECHO_card_remove,
.card_tick = ECHO_card_tick,
.card_register_reply = ECHO_card_register_reply,
static const struct xops echo_xops = {
.card_new = ECHO_card_new,
.card_init = ECHO_card_init,
.card_remove = ECHO_card_remove,
.card_tick = ECHO_card_tick,
.card_register_reply = ECHO_card_register_reply,
};
static const struct echoops echoops = {
.ec_set = ECHO_ec_set,
.ec_get = ECHO_ec_get,
.ec_update = ECHO_ec_update,
.ec_dump = ECHO_ec_dump,
static const struct echoops echoops = {
.ec_set = ECHO_ec_set,
.ec_get = ECHO_ec_get,
.ec_update = ECHO_ec_update,
.ec_dump = ECHO_ec_dump,
};
static xproto_table_t PROTO_TABLE(ECHO) = {
.owner = THIS_MODULE,
.entries = {
/* Table Card Opcode */
XENTRY( ECHO, ECHO, SET_REPLY ),
/* Table Card Opcode */
XENTRY(ECHO, ECHO, SET_REPLY),
},
.name = "ECHO",
.ports_per_subunit = 1,
@@ -288,7 +295,7 @@ static xproto_table_t PROTO_TABLE(ECHO) = {
static bool echo_packet_is_valid(xpacket_t *pack)
{
const xproto_entry_t *xe = NULL;
const xproto_entry_t *xe = NULL;
// DBG(GENERAL, "\n");
xe = xproto_card_entry(&PROTO_TABLE(ECHO), XPACKET_OP(pack));
return xe != NULL;
@@ -302,14 +309,14 @@ static void echo_packet_dump(const char *msg, xpacket_t *pack)
/*------------------------- sysfs stuff --------------------------------*/
static int echo_xpd_probe(struct device *dev)
{
xpd_t *ec_xpd;
int ret = 0;
xpd_t *ec_xpd;
int ret = 0;
ec_xpd = dev_to_xpd(dev);
/* Is it our device? */
if (ec_xpd->type != XPD_TYPE_ECHO) {
XPD_ERR(ec_xpd, "drop suggestion for %s (%d)\n", dev_name(dev),
ec_xpd->type);
XPD_ERR(ec_xpd, "drop suggestion for %s (%d)\n",
dev_name(dev), ec_xpd->type);
return -EINVAL;
}
XPD_DBG(DEVICES, ec_xpd, "SYSFS\n");
@@ -318,20 +325,23 @@ static int echo_xpd_probe(struct device *dev)
static int echo_xpd_remove(struct device *dev)
{
xpd_t *ec_xpd;
xpd_t *ec_xpd;
ec_xpd = dev_to_xpd(dev);
XPD_DBG(DEVICES, ec_xpd, "SYSFS\n");
return 0;
}
static struct xpd_driver echo_driver = {
.type = XPD_TYPE_ECHO,
.driver = {
.name = "echo",
.owner = THIS_MODULE,
.probe = echo_xpd_probe,
.remove = echo_xpd_remove}
static struct xpd_driver echo_driver = {
.type = XPD_TYPE_ECHO,
.driver = {
.name = "echo",
#ifndef OLD_HOTPLUG_SUPPORT
.owner = THIS_MODULE,
#endif
.probe = echo_xpd_probe,
.remove = echo_xpd_remove
}
};
static int __init card_echo_startup(void)

View File

@@ -24,8 +24,8 @@
#include "xpd.h"
enum echo_opcodes {
XPROTO_NAME(ECHO, SET) = 0x39,
XPROTO_NAME(ECHO, SET_REPLY) = 0x3A,
XPROTO_NAME(ECHO, SET) = 0x39,
XPROTO_NAME(ECHO, SET_REPLY) = 0x3A,
};
#endif /* CARD_ECHO_H */
#endif /* CARD_ECHO_H */

File diff suppressed because it is too large Load Diff

View File

@@ -25,16 +25,18 @@
#include "xpd.h"
enum fxo_opcodes {
XPROTO_NAME(FXO, SIG_CHANGED) = 0x06, /**/
XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, SIG_CHANGED) = 0x06,
/**/
XPROTO_NAME(FXO, DAA_WRITE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, XPD_STATE) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, CHAN_CID) = 0x0F, /* Write to DAA */
XPROTO_NAME(FXO, LED) = 0x0F, /* Write to DAA */
};
DEF_RPACKET_DATA(FXO, SIG_CHANGED,
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
#endif /* CARD_FXO_H */
#endif /* CARD_FXO_H */

File diff suppressed because it is too large Load Diff

View File

@@ -25,15 +25,18 @@
#include "xpd.h"
enum fxs_opcodes {
XPROTO_NAME(FXS, SIG_CHANGED) = 0x06,
/**/ XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, SIG_CHANGED) = 0x06,
/**/
XPROTO_NAME(FXS, XPD_STATE) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_POWER) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, CHAN_CID) = 0x0F, /* Write to SLIC */
XPROTO_NAME(FXS, LED) = 0x0F, /* Write to SLIC */
};
DEF_RPACKET_DATA(FXS, SIG_CHANGED,
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
#endif /* CARD_FXS_H */
DEF_RPACKET_DATA(FXS, SIG_CHANGED,
xpp_line_t sig_status; /* channels: lsb=1, msb=8 */
xpp_line_t sig_toggles; /* channels: lsb=1, msb=8 */
);
#endif /* CARD_FXS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -26,60 +26,88 @@
#include "xbus-pcm.h"
enum global_opcodes {
XPROTO_NAME(GLOBAL, AB_REQUEST) = 0x07,
XPROTO_NAME(GLOBAL, AB_DESCRIPTION) = 0x08,
XPROTO_NAME(GLOBAL, REGISTER_REQUEST) = 0x0F,
XPROTO_NAME(GLOBAL, REGISTER_REPLY) = 0x10,
/**/ XPROTO_NAME(GLOBAL, PCM_WRITE) = 0x11,
XPROTO_NAME(GLOBAL, PCM_READ) = 0x12,
/**/ XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
/**/ XPROTO_NAME(GLOBAL, ERROR_CODE) = 0x22,
XPROTO_NAME(GLOBAL, XBUS_RESET) = 0x23,
XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
XPROTO_NAME(GLOBAL, AB_REQUEST) = 0x07,
XPROTO_NAME(GLOBAL, AB_DESCRIPTION) = 0x08,
XPROTO_NAME(GLOBAL, REGISTER_REQUEST) = 0x0F,
XPROTO_NAME(GLOBAL, REGISTER_REPLY) = 0x10,
/**/
XPROTO_NAME(GLOBAL, PCM_WRITE) = 0x11,
XPROTO_NAME(GLOBAL, PCM_READ) = 0x12,
/**/
XPROTO_NAME(GLOBAL, SYNC_SOURCE) = 0x19,
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
/**/
XPROTO_NAME(GLOBAL, ERROR_CODE) = 0x22,
XPROTO_NAME(GLOBAL, RESET_SYNC_COUNTERS) = 0x23,
XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
};
struct unit_descriptor {
struct xpd_addr addr;
__u8 subtype:4;
__u8 type:4;
__u8 numchips;
__u8 ports_per_chip;
__u8 port_dir; /* bitmask: 0 - PSTN, 1 - PHONE */
__u8 reserved[2];
struct xpd_addr ec_addr;
struct xpd_addr addr;
byte subtype:4;
byte type:4;
byte numchips;
byte ports_per_chip;
byte port_dir; /* bitmask: 0 - PSTN, 1 - PHONE */
byte reserved[2];
struct xpd_addr ec_addr;
};
#define NUM_UNITS 6
DEF_RPACKET_DATA(GLOBAL, NULL_REPLY);
DEF_RPACKET_DATA(GLOBAL, AB_REQUEST, __u8 rev; __u8 reserved;);
DEF_RPACKET_DATA(GLOBAL, AB_DESCRIPTION, __u8 rev; __u8 reserved[3];
struct unit_descriptor unit_descriptor[NUM_UNITS];);
DEF_RPACKET_DATA(GLOBAL, REGISTER_REQUEST, reg_cmd_t reg_cmd;);
DEF_RPACKET_DATA(GLOBAL, PCM_WRITE, xpp_line_t lines; __u8 pcm[PCM_CHUNKSIZE];);
DEF_RPACKET_DATA(GLOBAL, PCM_READ, xpp_line_t lines; __u8 pcm[PCM_CHUNKSIZE];);
DEF_RPACKET_DATA(GLOBAL, SYNC_SOURCE, __u8 sync_mode; __u8 drift;);
DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY, __u8 sync_mode; __u8 drift;);
DEF_RPACKET_DATA(GLOBAL, REGISTER_REPLY, reg_cmd_t regcmd;);
DEF_RPACKET_DATA(GLOBAL, XBUS_RESET, __u8 mask;);
DEF_RPACKET_DATA(GLOBAL, ERROR_CODE, __u8 category_code; __u8 errorbits;
__u8 bad_packet[0];);
DEF_RPACKET_DATA(GLOBAL, AB_REQUEST,
byte rev;
byte reserved;
);
DEF_RPACKET_DATA(GLOBAL, AB_DESCRIPTION,
byte rev;
byte reserved[3];
struct unit_descriptor unit_descriptor[NUM_UNITS];
);
DEF_RPACKET_DATA(GLOBAL, REGISTER_REQUEST,
reg_cmd_t reg_cmd;
);
DEF_RPACKET_DATA(GLOBAL, PCM_WRITE,
xpp_line_t lines;
byte pcm[PCM_CHUNKSIZE];
);
DEF_RPACKET_DATA(GLOBAL, PCM_READ,
xpp_line_t lines;
byte pcm[PCM_CHUNKSIZE];
);
DEF_RPACKET_DATA(GLOBAL, SYNC_SOURCE,
byte sync_mode;
byte drift;
);
DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
byte sync_mode;
byte drift;
);
DEF_RPACKET_DATA(GLOBAL, REGISTER_REPLY,
reg_cmd_t regcmd;
);
DEF_RPACKET_DATA(GLOBAL, RESET_SYNC_COUNTERS,
byte mask;
);
DEF_RPACKET_DATA(GLOBAL, ERROR_CODE,
byte category_code;
byte errorbits;
byte bad_packet[0];
);
/* 0x07 */ DECLARE_CMD(GLOBAL, AB_REQUEST);
/* 0x19 */ DECLARE_CMD(GLOBAL, SYNC_SOURCE, enum sync_mode mode, int drift);
/* 0x23 */ DECLARE_CMD(GLOBAL, RESET_SPI);
/* 0x23 */ DECLARE_CMD(GLOBAL, RESET_SYNC_COUNTERS);
int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
bool writing, __u8 regnum, bool do_subreg, __u8 subreg,
__u8 data_low, bool do_datah, __u8 data_high,
bool should_reply);
bool writing, byte regnum, bool do_subreg, byte subreg,
byte data_low, bool do_datah, byte data_high, bool should_reply);
int send_multibyte_request(xbus_t *xbus, unsigned unit, xportno_t portno,
bool eoftx, __u8 *buf, unsigned len);
bool eoftx, byte *buf, unsigned len);
extern xproto_table_t PROTO_TABLE(GLOBAL);
int run_initialize_registers(xpd_t *xpd);
int parse_chip_command(xpd_t *xpd, char *cmdline);
extern charp initdir;
#endif /* CARD_GLOBAL_H */
#endif /* CARD_GLOBAL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,8 @@
#include "xpd.h"
enum pri_opcodes {
XPROTO_NAME(PRI, SET_LED) = 0x33,
XPROTO_NAME(PRI, SET_LED) = 0x33,
};
#endif /* CARD_PRI_H */
#endif /* CARD_PRI_H */

View File

@@ -20,6 +20,11 @@
*
*/
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
# warning "This module is tested only with 2.6 kernels"
#endif
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
@@ -30,48 +35,57 @@
static const char rcsid[] = "$Id$";
#define P_(x) [ x ] = { .value = x, .name = #x, }
static struct {
static struct {
int value;
char *name;
} poll_names[] = {
P_(POLLIN), P_(POLLPRI), P_(POLLOUT), P_(POLLERR), P_(POLLHUP),
P_(POLLNVAL), P_(POLLRDNORM), P_(POLLRDBAND), P_(POLLWRNORM),
P_(POLLWRBAND), P_(POLLMSG), P_(POLLREMOVE)
P_(POLLIN),
P_(POLLPRI),
P_(POLLOUT),
P_(POLLERR),
P_(POLLHUP),
P_(POLLNVAL),
P_(POLLRDNORM),
P_(POLLRDBAND),
P_(POLLWRNORM),
P_(POLLWRBAND),
P_(POLLMSG),
P_(POLLREMOVE)
};
#undef P_
void dump_poll(int debug, const char *msg, int poll)
{
int i;
int i;
for (i = 0; i < ARRAY_SIZE(poll_names); i++) {
if (poll & poll_names[i].value)
for(i = 0; i < ARRAY_SIZE(poll_names); i++) {
if(poll & poll_names[i].value)
DBG(GENERAL, "%s: %s\n", msg, poll_names[i].name);
}
}
EXPORT_SYMBOL(dump_poll);
void alarm2str(int alarm, char *buf, int buflen)
{
char *p = buf;
int left = buflen;
int i;
int n;
char *p = buf;
int left = buflen;
int i;
int n;
if (!alarm) {
if(!alarm) {
snprintf(buf, buflen, "NONE");
return;
}
memset(buf, 0, buflen);
for (i = 0; i < 8; i++) {
if (left && (alarm & BIT(i))) {
for(i = 0; i < 8; i++) {
if(left && (alarm & BIT(i))) {
n = snprintf(p, left, "%s,", alarmbit2str(i));
p += n;
left -= n;
}
}
if (p > buf) /* kill last comma */
if(p > buf) /* kill last comma */
*(p - 1) = '\0';
}
EXPORT_SYMBOL(dump_poll);
EXPORT_SYMBOL(alarm2str);

View File

@@ -26,76 +26,55 @@
/* Debugging Macros */
#define PRINTK(level, category, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: " fmt, \
#level, category, THIS_MODULE->name, ## __VA_ARGS__)
#define PRINTK(level, category, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: " fmt, #level, category, THIS_MODULE->name, ## __VA_ARGS__)
#define XBUS_PRINTK(level, category, xbus, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s: " fmt, #level, \
#define XBUS_PRINTK(level, category, xbus, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s: " fmt, #level, \
category, THIS_MODULE->name, (xbus)->busname, ## __VA_ARGS__)
#define XPD_PRINTK(level, category, xpd, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s: " fmt, #level, \
category, THIS_MODULE->name, \
(xpd)->xbus->busname, (xpd)->xpdname, ## __VA_ARGS__)
#define XPD_PRINTK(level, category, xpd, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s: " fmt, #level, \
category, THIS_MODULE->name, (xpd)->xbus->busname, (xpd)->xpdname, ## __VA_ARGS__)
#define LINE_PRINTK(level, category, xpd, pos, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s/%d: " fmt, #level, \
category, THIS_MODULE->name, \
(xpd)->xbus->busname, (xpd)->xpdname, (pos), ## __VA_ARGS__)
#define LINE_PRINTK(level, category, xpd, pos, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s/%s/%d: " fmt, #level, \
category, THIS_MODULE->name, (xpd)->xbus->busname, (xpd)->xpdname, (pos), ## __VA_ARGS__)
#define PORT_PRINTK(level, category, xbus, unit, port, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s UNIT=%d PORT=%d: " fmt, #level, \
category, THIS_MODULE->name, \
(xbus)->busname, (unit), (port), ## __VA_ARGS__)
#define PORT_PRINTK(level, category, xbus, unit, port, fmt, ...) \
printk(KERN_ ## level "%s%s-%s: %s UNIT=%d PORT=%d: " fmt, #level, \
category, THIS_MODULE->name, (xbus)->busname, (unit), (port), ## __VA_ARGS__)
#define DBG(bits, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && \
PRINTK(DEBUG, "-" #bits, "%s: " fmt, \
__func__, ## __VA_ARGS__)))
#define DBG(bits, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && PRINTK(DEBUG, "-" #bits, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)))
#define INFO(fmt, ...) PRINTK(INFO, "", fmt, ## __VA_ARGS__)
#define NOTICE(fmt, ...) PRINTK(NOTICE, "", fmt, ## __VA_ARGS__)
#define WARNING(fmt, ...) PRINTK(WARNING, "", fmt, ## __VA_ARGS__)
#define ERR(fmt, ...) PRINTK(ERR, "", fmt, ## __VA_ARGS__)
#define XBUS_DBG(bits, xbus, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XBUS_PRINTK(DEBUG, "-" #bits, \
xbus, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define XBUS_INFO(xbus, fmt, ...) \
XBUS_PRINTK(INFO, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_NOTICE(xbus, fmt, ...) \
XBUS_PRINTK(NOTICE, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_ERR(xbus, fmt, ...) \
XBUS_PRINTK(ERR, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_DBG(bits, xbus, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XBUS_PRINTK(DEBUG, "-" #bits, xbus, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)))
#define XBUS_INFO(xbus, fmt, ...) XBUS_PRINTK(INFO, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_NOTICE(xbus, fmt, ...) XBUS_PRINTK(NOTICE, "", xbus, fmt, ## __VA_ARGS__)
#define XBUS_ERR(xbus, fmt, ...) XBUS_PRINTK(ERR, "", xbus, fmt, ## __VA_ARGS__)
#define XPD_DBG(bits, xpd, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XPD_PRINTK(DEBUG, "-" #bits, \
xpd, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define XPD_INFO(xpd, fmt, ...) \
XPD_PRINTK(INFO, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_NOTICE(xpd, fmt, ...) \
XPD_PRINTK(NOTICE, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_WARNING(xpd, fmt, ...) \
XPD_PRINTK(WARNING, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_ERR(xpd, fmt, ...) \
XPD_PRINTK(ERR, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_DBG(bits, xpd, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && XPD_PRINTK(DEBUG, "-" #bits, xpd, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)))
#define XPD_INFO(xpd, fmt, ...) XPD_PRINTK(INFO, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_NOTICE(xpd, fmt, ...) XPD_PRINTK(NOTICE, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_WARNING(xpd, fmt, ...) XPD_PRINTK(WARNING, "", xpd, fmt, ## __VA_ARGS__)
#define XPD_ERR(xpd, fmt, ...) XPD_PRINTK(ERR, "", xpd, fmt, ## __VA_ARGS__)
#define LINE_DBG(bits, xpd, pos, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && LINE_PRINTK(DEBUG, "-" #bits, \
xpd, pos, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define LINE_NOTICE(xpd, pos, fmt, ...) \
LINE_PRINTK(NOTICE, "", xpd, pos, fmt, ## __VA_ARGS__)
#define LINE_ERR(xpd, pos, fmt, ...) \
LINE_PRINTK(ERR, "", xpd, pos, fmt, ## __VA_ARGS__)
#define LINE_DBG(bits, xpd, pos, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && LINE_PRINTK(DEBUG, "-" #bits, xpd, pos, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)))
#define LINE_NOTICE(xpd, pos, fmt, ...) LINE_PRINTK(NOTICE, "", xpd, pos, fmt, ## __VA_ARGS__)
#define LINE_ERR(xpd, pos, fmt, ...) LINE_PRINTK(ERR, "", xpd, pos, fmt, ## __VA_ARGS__)
#define PORT_DBG(bits, xbus, unit, port, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && \
PORT_PRINTK(DEBUG, "-" #bits, \
xbus, unit, port, "%s: " fmt, __func__, ## __VA_ARGS__)))
#define PORT_NOTICE(xbus, unit, port, fmt, ...) \
PORT_PRINTK(NOTICE, "", xbus, unit, port, fmt, ## __VA_ARGS__)
#define PORT_ERR(xbus, unit, port, fmt, ...) \
PORT_PRINTK(ERR, "", xbus, unit, port, fmt, ## __VA_ARGS__)
#define PORT_DBG(bits, xbus, unit, port, fmt, ...) \
((void)((debug & (DBG_ ## bits)) && PORT_PRINTK(DEBUG, "-" #bits, \
xbus, unit, port, "%s: " fmt, __FUNCTION__, ## __VA_ARGS__)))
#define PORT_NOTICE(xbus, unit, port, fmt, ...) PORT_PRINTK(NOTICE, "", xbus, unit, port, fmt, ## __VA_ARGS__)
#define PORT_ERR(xbus, unit, port, fmt, ...) PORT_PRINTK(ERR, "", xbus, unit, port, fmt, ## __VA_ARGS__)
/*
* Bits for debug
@@ -115,98 +94,63 @@ void dump_poll(int debug, const char *msg, int poll);
static inline char *rxsig2str(enum dahdi_rxsig sig)
{
switch (sig) {
case DAHDI_RXSIG_ONHOOK:
return "ONHOOK";
case DAHDI_RXSIG_OFFHOOK:
return "OFFHOOK";
case DAHDI_RXSIG_START:
return "START";
case DAHDI_RXSIG_RING:
return "RING";
case DAHDI_RXSIG_INITIAL:
return "INITIAL";
switch(sig) {
case DAHDI_RXSIG_ONHOOK: return "ONHOOK";
case DAHDI_RXSIG_OFFHOOK: return "OFFHOOK";
case DAHDI_RXSIG_START: return "START";
case DAHDI_RXSIG_RING: return "RING";
case DAHDI_RXSIG_INITIAL: return "INITIAL";
}
return "Unknown rxsig";
}
static inline char *txsig2str(enum dahdi_txsig sig)
{
switch (sig) {
case DAHDI_TXSIG_ONHOOK:
return "TXSIG_ONHOOK";
case DAHDI_TXSIG_OFFHOOK:
return "TXSIG_OFFHOOK";
case DAHDI_TXSIG_START:
return "TXSIG_START";
case DAHDI_TXSIG_KEWL:
return "TXSIG_KEWL"; /* Drop battery if possible */
case DAHDI_TXSIG_TOTAL:
break;
switch(sig) {
case DAHDI_TXSIG_ONHOOK: return "TXSIG_ONHOOK";
case DAHDI_TXSIG_OFFHOOK: return "TXSIG_OFFHOOK";
case DAHDI_TXSIG_START: return "TXSIG_START";
case DAHDI_TXSIG_KEWL: return "TXSIG_KEWL"; /* Drop battery if possible */
case DAHDI_TXSIG_TOTAL: break;
}
return "Unknown txsig";
}
static inline char *event2str(int event)
{
switch (event) {
case DAHDI_EVENT_NONE:
return "NONE";
case DAHDI_EVENT_ONHOOK:
return "ONHOOK";
case DAHDI_EVENT_RINGOFFHOOK:
return "RINGOFFHOOK";
case DAHDI_EVENT_WINKFLASH:
return "WINKFLASH";
case DAHDI_EVENT_ALARM:
return "ALARM";
case DAHDI_EVENT_NOALARM:
return "NOALARM";
case DAHDI_EVENT_ABORT:
return "ABORT";
case DAHDI_EVENT_OVERRUN:
return "OVERRUN";
case DAHDI_EVENT_BADFCS:
return "BADFCS";
case DAHDI_EVENT_DIALCOMPLETE:
return "DIALCOMPLETE";
case DAHDI_EVENT_RINGERON:
return "RINGERON";
case DAHDI_EVENT_RINGEROFF:
return "RINGEROFF";
case DAHDI_EVENT_HOOKCOMPLETE:
return "HOOKCOMPLETE";
case DAHDI_EVENT_BITSCHANGED:
return "BITSCHANGED";
case DAHDI_EVENT_PULSE_START:
return "PULSE_START";
case DAHDI_EVENT_TIMER_EXPIRED:
return "TIMER_EXPIRED";
case DAHDI_EVENT_TIMER_PING:
return "TIMER_PING";
case DAHDI_EVENT_POLARITY:
return "POLARITY";
switch(event) {
case DAHDI_EVENT_NONE: return "NONE";
case DAHDI_EVENT_ONHOOK: return "ONHOOK";
case DAHDI_EVENT_RINGOFFHOOK: return "RINGOFFHOOK";
case DAHDI_EVENT_WINKFLASH: return "WINKFLASH";
case DAHDI_EVENT_ALARM: return "ALARM";
case DAHDI_EVENT_NOALARM: return "NOALARM";
case DAHDI_EVENT_ABORT: return "ABORT";
case DAHDI_EVENT_OVERRUN: return "OVERRUN";
case DAHDI_EVENT_BADFCS: return "BADFCS";
case DAHDI_EVENT_DIALCOMPLETE: return "DIALCOMPLETE";
case DAHDI_EVENT_RINGERON: return "RINGERON";
case DAHDI_EVENT_RINGEROFF: return "RINGEROFF";
case DAHDI_EVENT_HOOKCOMPLETE: return "HOOKCOMPLETE";
case DAHDI_EVENT_BITSCHANGED: return "BITSCHANGED";
case DAHDI_EVENT_PULSE_START: return "PULSE_START";
case DAHDI_EVENT_TIMER_EXPIRED: return "TIMER_EXPIRED";
case DAHDI_EVENT_TIMER_PING: return "TIMER_PING";
case DAHDI_EVENT_POLARITY: return "POLARITY";
}
return "Unknown event";
}
static inline char *hookstate2str(int hookstate)
{
switch (hookstate) {
case DAHDI_ONHOOK:
return "DAHDI_ONHOOK";
case DAHDI_START:
return "DAHDI_START";
case DAHDI_OFFHOOK:
return "DAHDI_OFFHOOK";
case DAHDI_WINK:
return "DAHDI_WINK";
case DAHDI_FLASH:
return "DAHDI_FLASH";
case DAHDI_RING:
return "DAHDI_RING";
case DAHDI_RINGOFF:
return "DAHDI_RINGOFF";
switch(hookstate) {
case DAHDI_ONHOOK: return "DAHDI_ONHOOK";
case DAHDI_START: return "DAHDI_START";
case DAHDI_OFFHOOK: return "DAHDI_OFFHOOK";
case DAHDI_WINK: return "DAHDI_WINK";
case DAHDI_FLASH: return "DAHDI_FLASH";
case DAHDI_RING: return "DAHDI_RING";
case DAHDI_RINGOFF: return "DAHDI_RINGOFF";
}
return "Unknown hookstate";
}
@@ -215,42 +159,25 @@ static inline char *hookstate2str(int hookstate)
static inline char *sig2str(int sig)
{
switch (sig) {
case DAHDI_SIG_FXSLS:
return "FXSLS";
case DAHDI_SIG_FXSKS:
return "FXSKS";
case DAHDI_SIG_FXSGS:
return "FXSGS";
case DAHDI_SIG_FXOLS:
return "FXOLS";
case DAHDI_SIG_FXOKS:
return "FXOKS";
case DAHDI_SIG_FXOGS:
return "FXOGS";
case DAHDI_SIG_EM:
return "E&M";
case DAHDI_SIG_EM_E1:
return "E&M-E1";
case DAHDI_SIG_CLEAR:
return "Clear";
case DAHDI_SIG_HDLCRAW:
return "HDLCRAW";
case DAHDI_SIG_HDLCFCS:
return "HDLCFCS";
case DAHDI_SIG_HDLCNET:
return "HDLCNET";
case DAHDI_SIG_SLAVE:
return "Slave";
case DAHDI_SIG_CAS:
return "CAS";
case DAHDI_SIG_DACS:
return "DACS";
case DAHDI_SIG_DACS_RBS:
return "DACS+RBS";
case DAHDI_SIG_SF:
return "SF (ToneOnly)";
case DAHDI_SIG_NONE:
break;
case DAHDI_SIG_FXSLS: return "FXSLS";
case DAHDI_SIG_FXSKS: return "FXSKS";
case DAHDI_SIG_FXSGS: return "FXSGS";
case DAHDI_SIG_FXOLS: return "FXOLS";
case DAHDI_SIG_FXOKS: return "FXOKS";
case DAHDI_SIG_FXOGS: return "FXOGS";
case DAHDI_SIG_EM: return "E&M";
case DAHDI_SIG_EM_E1: return "E&M-E1";
case DAHDI_SIG_CLEAR: return "Clear";
case DAHDI_SIG_HDLCRAW: return "HDLCRAW";
case DAHDI_SIG_HDLCFCS: return "HDLCFCS";
case DAHDI_SIG_HDLCNET: return "HDLCNET";
case DAHDI_SIG_SLAVE: return "Slave";
case DAHDI_SIG_CAS: return "CAS";
case DAHDI_SIG_DACS: return "DACS";
case DAHDI_SIG_DACS_RBS: return "DACS+RBS";
case DAHDI_SIG_SF: return "SF (ToneOnly)";
case DAHDI_SIG_NONE:
break;
}
return "Unconfigured";
}
@@ -258,25 +185,18 @@ static inline char *sig2str(int sig)
static inline char *alarmbit2str(int alarmbit)
{
/* from dahdi/kernel.h */
switch (1 << alarmbit) {
case DAHDI_ALARM_NONE:
return "NONE";
case DAHDI_ALARM_RECOVER:
return "RECOVER";
case DAHDI_ALARM_LOOPBACK:
return "LOOPBACK";
case DAHDI_ALARM_YELLOW:
return "YELLOW";
case DAHDI_ALARM_RED:
return "RED";
case DAHDI_ALARM_BLUE:
return "BLUE";
case DAHDI_ALARM_NOTOPEN:
return "NOTOPEN";
switch(1 << alarmbit) {
case DAHDI_ALARM_NONE: return "NONE";
case DAHDI_ALARM_RECOVER: return "RECOVER";
case DAHDI_ALARM_LOOPBACK: return "LOOPBACK";
case DAHDI_ALARM_YELLOW: return "YELLOW";
case DAHDI_ALARM_RED: return "RED";
case DAHDI_ALARM_BLUE: return "BLUE";
case DAHDI_ALARM_NOTOPEN: return "NOTOPEN";
}
return "UNKNOWN";
}
void alarm2str(int alarm, char *buf, int buflen);
#endif /* DAHDI_DEBUG_H */
#endif /* DAHDI_DEBUG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,10 @@
# Install firmwares and initialization scripts for the Astribank
# drivers
USB_FW = USB_FW.hex USB_FW.201.hex USB_RECOV.hex
FPGA_FW = FPGA_FXS.hex FPGA_1141.hex FPGA_1151.hex FPGA_1161.hex \
FPGA_1161.201.hex FPGA_1161.202.hex
FPGA_FW = FPGA_FXS.hex FPGA_1141.hex FPGA_1151.hex FPGA_1161.hex
PIC_FW = PIC_TYPE_1.hex PIC_TYPE_2.hex PIC_TYPE_3.hex PIC_TYPE_4.hex
OCT_FW = $(wildcard OCT6104E-256D.ima)
FIRMWARES = $(USB_FW) $(FPGA_FW) $(PIC_FW) $(OCT_FW)
FIRMWARES = USB_FW.hex $(FPGA_FW) $(PIC_FW) $(OCT_FW)
PROTO_VER = 30
SCRIPTS_BASE = $(patsubst %,init_card_%_$(PROTO_VER),1 2 3 4 5)
SCRIPTS = $(SCRIPTS_BASE:%=../%)
@@ -20,7 +18,4 @@ install:
mkdir -p $(TARGET)
install $(SCRIPTS) $(TARGET)/
install -m 644 ../XppConfig.pm $(FIRMWARES) $(TARGET)/
if [ ! -r $(TARGET)/USB_FW.202.hex ]; then \
ln -s USB_FW.201.hex $(TARGET)/USB_FW.202.hex;\
fi

View File

@@ -1,5 +1,5 @@
#
# $Id: PIC_TYPE_1.hex 9841 2011-09-08 17:00:23Z dima $
# $Id: PIC_TYPE_1.hex 7498 2009-11-17 11:38:56Z dima $
#
:03000000A1EA4A28
:03000100C41C41DB
@@ -31,8 +31,8 @@
:03001B00D00D0005
:03001C00A17A17AF
:03001D0080080058
:03001E00C0010B13
:03001F0019A038ED
:03001E00C0710BA3
:03001F0016603830
:03002000743C0627
:03002100A26D804D
:03002200C01024E7
@@ -42,370 +42,370 @@
:03002600C03030B7
:0300270018C901F4
:030028006432043B
:03002900A4A03060
:03002900A4C03040
:03002A0020C901E9
:03002B007432022A
:03002C00AE803073
:03002D00C4090102
:03002E00D80C806B
:03002F00024FFF7E
:03003000C00164A8
:03003100022C108E
:03003200209FFF0D
:0300330003015076
:03003400901D0814
:030035002046B9A9
:03003600030D10A7
:0300370090102204
:0300380020220182
:0300390003003091
:03003A0090190119
:03003B00C11204EB
:03003C0019003078
:03003D0064390122
:03003E00A43202E7
:03003F00C22030AC
:030040001909019A
:0300410074380010
:03004200A46214A1
:03004300209E708C
:030044001253084C
:03004500A4930879
:03004600209308FC
:03004700FFF308BC
:0300480016502728
:03004900AE88007E
:03004A00209C00F7
:03004B0014503915
:03004C00643038E5
:03004D00A8603F69
:03004E00C40C07D8
:03004F00D80D4089
:0300500002403437
:03005100C00C08D8
:0300520002203851
:03005300209219DF
:03005400030E0791
:03005500901020E8
:03005600204360E4
:0300570003036040
:03005800901360A2
:0300590020236001
:03005A00030C1084
:03005B00901038CA
:03005C00C11219B5
:03005D00190E0772
:03005E00643120EA
:03005F00A64C109C
:03006000C221803A
:03006100190E7005
:03006200743743AD
:03006300A86A7315
:03006400C44C0287
:03006500D801803F
:03006600024E0740
:03006700C006438D
:03006800022A76F3
:03006900209C03D5
:03006A000301800F
:03006B00901E07DD
:03006C00204643E8
:03006D00030A760D
:03006E00901C04DF
:03006F00202180CD
:03007000030E0775
:03007100901643A3
:03007200210A76EA
:03007300E03C016D
:03007400743038AD
:03007500C04A7509
:03007600190C184A
:030077007480385A
:03007800A8621962
:03007900C04E0F67
:03007A00FFF03D57
:03007B00150C0061
:03007C00643038B5
:03007D00A81C02BA
:03007E002091804E
:03007F0013EE0776
:03008000A847434B
:03008100209A863C
:03008200FFFC3F41
:0300830017E03152
:0300840021EC1656
:03008500035A9388
:03008600C14C0367
:03008700D801801D
:03008800024E071E
:03008900C007436A
:03008A00022A8FB8
:03008B00209CFFB7
:03008C000300313D
:03008D00901C18AC
:03008E00204A9372
:03008F00030C035C
:030090009010319C
:03009100202C120E
:03009200030A93CB
:0300930090103C8E
:03009400210E0F2B
:0300950002709D59
:03009600C147035C
:03009700024A9D7D
:03009800209C0F9A
:03009900030FFF53
:03009A0090115C66
:03009B0020411DE4
:03009C00030A9EB6
:03009D0090121CA2
:03009E002070309F
:03009F00030E0F3E
:0300A00090103C81
:0300A100C18C020D
:0300A200D800394A
:0300A300024C000C
:0300A400C0003960
:0300A500022C80AA
:0300A60020902483
:0300A700030C083F
:0300A800901104B0
:0300A900204039BB
:0300AA00030C0044
:0300AB0090103979
:0300AC00202C0005
:0300AD0003003A13
:0300AE009010258A
:0300AF0021003EEF
:0300B00003B02B6F
:0300B100707C035D
:0300B200AB602C14
:0300B300209C404E
:0300B40013F0390D
:0300B500ABE7D9DD
:0300B600209AB5D8
:0300B70015FC0035
:0300B800643208A7
:0300B900AE8030E6
:0300BA0069B90120
:0300BB00AE8C8088
:0300BC0020920887
:0300BD001BF03005
:0300BE00C5090170
:0300BF00039C405F
:0300C000799039FB
:0300C100AC06D9B1
:0300C20020BAC69B
:0300C300D006F96B
:0300C400038BC9E2
:0300C500219AC1BC
:0300C600E079429C
:0300C700348C0274
:0300C80034818000
:0300C900348E076B
:0300CA0034874335
:0300CB00030AE73E
:0300CC0021AC065E
:0300CD00348195E6
:0300CE0034874331
:0300CF00348AE789
:0300D0003487D39F
:0300D100D05AE71B
:0300D200031C0606
:0300D300C00187E2
:0300D400032743BC
:0300D500033AD813
:0300D600C70C0351
:0300D700039AE5A4
:0300D800C50C074D
:0300D90003918709
:0300DA00C1874398
:0300DB00030ADE37
:0300DC00C00C0154
:0300DD00031AE51E
:0300DE0021BC033F
:0300DF0003218773
:0300E000C0074313
:0300E100033AE4FB
:0300E200C70C0048
:0300E300039AE598
:0300E400C502074B
:0300E5000390275E
:0300E600C40AF455
:0300E700039C0671
:0300E800369195B9
:0300E900C01643FB
:0300EA001FAAF456
:0300EB0021CC0124
:0300EC0009A1C7A0
:0300ED0074309CD0
:0300EE00A1E70384
:0300EF0003AAF46D
:0300F000C02CFF22
:0300F100FFF022FB
:0300F20016B0271E
:0300F300C02B5CC3
:0300F40023EC00FA
:0300F5007436F36B
:0300F60012BCFF3A
:0300F70020B02115
:0300F800038C0175
:0300F900C44024DC
:0300FA0003990A5D
:0300FB00C406B385
:0300FC00039B83E0
:0300FD00C00C0133
:0300FE0002302F9E
:0300FF00ABF2154C
:03010000B006D373
:03010100000D806E
:03010200000024D6
:03010300000217E0
:03010400000022D6
:03010500000C06E5
:0301060000019560
:03010700000743AB
:03010800000B4B9E
:030109000006D31A
:03010A00000B4B9C
:03010B00000CE005
:03010C0000015798
:03010D00000643A6
:03010E00000B4B98
:03010F00000C00E1
:030110000007B72E
:03011100000C05DA
:030112000007D70C
:03011300000C10CD
:030114000007F7EA
:03011500000C02D9
:03011600000027BF
:03011700000C10C9
:03011800000D02D5
:03011900000FFFD5
:03011A000001429F
:03011B0000069744
:03011C00000D02D1
:03011D00000637A2
:03011E00000D10C1
:03011F00000022BB
:03012000000C8050
:03012100000124B6
:03012200000C02CC
:0301230000018058
:03012400000E07C3
:030125000007438D
:03012600000B3992
:03012700000C05C4
:030128000001478C
:030129000006438A
:03012A00000B398E
:03012B00000C01C4
:03012C000001814E
:03012D0000074385
:03012E00000B3291
:03012F00000C10B1
:03013000000021AB
:03013100000B3987
:03013200000C10AE
:0301330000018147
:030134000007437E
:03013500000B3983
:03013600000C209A
:03013700000021A4
:03013800000B3980
:03013900000201C0
:03013A0000003092
:03013B00000901B7
:03013C00000204BA
:03013D000000308F
:03013E00000901B4
:03013F00000202B9
:030140000000308C
:03014100000901B1
:03014200000C802E
:03014300000FFFAB
:0301440000016453
:03014500000207AE
:0301460000016253
:03014700000FFFA7
:0301480000015063
:03014900000D089E
:03014A000001228F
:03014B00000201AE
:03014C0000003080
:03014D00000901A5
:03014E00000204A8
:03014F000000307D
:03015000000901A2
:03015100000202A7
:030152000000307A
:030153000009019F
:03015400000C009C
:0301550000002F78
:030156000007D3CC
:03015700000B7E1C
:0301580000021092
:0301590000002281
:03015A0000020E92
:03015B000000277A
:03015C00000C5044
:03015D0000003966
:03015E00000799FE
:03015F00000B5E34
:0301600000021288
:030161000000306B
:0301620000021484
:0301630000003168
:0301640000021383
:030165000006B3DE
:03016600000D1079
:0301670000003263
:03016800000C0088
:0301690000003360
:03016A00000C7016
:03016B0000003958
:03016C00000C5034
:03016D0000003956
:03016E0000021577
:03016F000000305D
:0301700000021674
:030171000000315A
:0301720000020286
:0301730000003257
:03002C00AFA03052
:03002D0020990116
:03002E00021C8031
:03002F00C40FFFFC
:03003000D8016490
:03003100024C106E
:03003200C00FFFFD
:0300330002215057
:03003400201D0884
:030035000306B906
:03003600901D100A
:0300370020402244
:03003800030201BF
:03003900901030F4
:03003A0020290179
:03003B00030204B9
:03003C00901030F1
:03003D00C11901E5
:03003E00190202A2
:03003F00643030FA
:03004000A45901BF
:03004100C22800D2
:030042001902148C
:03004300743E7098
:03004400A483088A
:03004500209308FD
:030046001253084A
:03004700A4B30857
:03004800209027DE
:03004900FFF800BD
:03004A00165C0041
:03004B00AFA0392A
:03004C00209038C9
:03004D00145C0739
:03004E00643D40CE
:03004F00A8C03412
:03005000209C08E9
:0300510002103862
:03005200C40219CC
:03005300D80E07BD
:0300540002402047
:03005500C0036085
:0300560002236022
:0300570020136013
:030058000303603F
:03005900901C10E8
:03005A002040380B
:03005B0003021984
:03005C00901E07EC
:03005D002021203F
:03005E00030C1080
:03005F009011807D
:03006000C11E704E
:0300610019074339
:03006200643A6D90
:03006300A68C0266
:03006400C2218036
:03006500190E036E
:03006600743643AA
:03006700A8CA70B4
:03006800209C03D6
:0300690002118001
:03006A00C44E037E
:03006B00D8064371
:03006C00024A70D5
:03006D00C00C01C3
:03006E0002203835
:03006F00201A6FE5
:03007000030C1866
:03007100901038B4
:0300720020421910
:03007300030E0F6A
:0300740090103DAC
:03007500202C003C
:030076000300384C
:03007700901C02D8
:03007800210180E3
:03007900E03E0363
:03007A0074374395
:03007B00C04A80F8
:03007C00190C3F1D
:03007D007480315B
:03007E00A8CC16F5
:03007F00C04A84F0
:03008000FFFCFF83
:0300810015003136
:03008200643C18C3
:03008300A87A84D4
:0300840020903C8D
:0300850013EE0F68
:03008600A8A09D92
:03008700209703BC
:03008800FFFA8EEE
:0300890017EC0F62
:03008A0021EFFF64
:03008B0003515CC2
:03008C00C1411D52
:03008D00D80A8FFF
:03008E0002421C0F
:03008F00C000307E
:03009000022E0F2E
:0300910020103C00
:03009200030C025A
:0300930090103991
:03009400204C00FD
:030095000300392C
:03009600901C803B
:0300970020202402
:03009800030C084E
:03009900901104BF
:03009A0021003909
:03009B00E01C0066
:03009C00027039B6
:03009D00C18C0013
:03009E00D8002661
:03009F00024025F7
:0300A000C0003E5F
:0300A10002202B0F
:0300A200201C031C
:0300A30003002C2B
:0300A400901C00AD
:0300A500204208EE
:0300A60003003024
:0300A700901901AC
:0300A800202C8089
:0300A90003020847
:0300AA0090103083
:0300AB0021090127
:0300AC0003BC4052
:0300AD00C1403916
:0300AE000246D92E
:0300AF00C01AB3C1
:0300B0000226F92C
:0300B100201BB65B
:0300B200030AAE90
:0300B3009019425F
:0300B400204C02DB
:0300B500030180C4
:0300B600901E0396
:0300B7002077436C
:0300B800030AD464
:0300B900901C0692
:0300BA0021A195EC
:0300BB00141743D4
:0300BC00707AD483
:0300BD00AC07D3BA
:0300BE00181AD439
:0300BF00AC3C0650
:0300C00069B1879C
:0300C100AFA743A3
:0300C200F00AC57C
:0300C300228C0389
:0300C400643AD2C9
:0300C500AFAC07D6
:0300C6001BA187F4
:0300C700C107432B
:0300C800FFFACB71
:0300C90017BC0160
:0300CA0021AAD296
:0300CB00141C03FF
:0300CC0064318715
:0300CD00AD074339
:0300CE00C10AD193
:0300CF0013BC005F
:0300D000C50AD28C
:0300D10003920790
:0300D200799027FB
:0300D300AD2AE172
:0300D40020BC0647
:0300D500D00195C2
:0300D6000386435B
:0300D700219AE18A
:0300D800E07C01C8
:0300D9003481C7A8
:0300DA0034809CD3
:0300DB0034870364
:0300DC00348AE182
:0300DD00030CFF12
:0300DE002060227D
:0300DF0034802743
:0300E000348B4915
:0300E100348C005C
:0300E2003486F36E
:0300E300D05CFFEF
:0300E400031021E5
:0300E500C00C014B
:0300E600032024D0
:0300E70003390AD0
:0300E800C706B395
:0300E900039B7006
:0300EA00C50C0141
:0300EB0003902F50
:0300EC00C18215B9
:0300ED000306D334
:0300EE00C00D80C2
:0300EF00031024D7
:0300F00021B21723
:0300F100032022C7
:0300F200C00C0639
:0300F30003319541
:0300F400C70743F8
:0300F500039B3832
:0300F600C506D369
:0300F700039B3830
:0300F800C40CE055
:0300F90003915719
:0300FA00369643F4
:0300FB00C01B38EF
:0300FC001E6C0077
:0300FD0021C7B761
:0300FE00086C0586
:0300FF007437D77C
:03010000A1EC105F
:030101000267F79B
:03010200C02C020C
:03010300FFF027E3
:0301040016BC1016
:03010500C02D0208
:0301060023EFFFE5
:030107007431420E
:0301080012B69795
:0301090020BD0214
:03010A0003863732
:03010B00C44D10D0
:03010C000390223B
:03010D00C40C809F
:03010E0003912436
:03010F00C00C021F
:0301100002318039
:03011100AACE0370
:03011200B12743CF
:03011300000B26B8
:03011400000C05D7
:030115000001479F
:030116000006439D
:03011700000B26B4
:03011800000C01D7
:0301190000018161
:03011A0000074398
:03011B00000B1FB7
:03011C00000C10C4
:03011D00000021BE
:03011E00000B26AD
:03011F00000C10C1
:030120000001815A
:0301210000074391
:03012200000B26A9
:03012300000C20AD
:03012400000021B7
:03012500000B26A6
:03012600000201D3
:03012700000030A5
:03012800000901CA
:03012900000204CD
:03012A00000030A2
:03012B00000901C7
:03012C00000202CC
:03012D000000309F
:03012E00000901C4
:03012F00000C8041
:03013000000FFFBE
:0301310000016466
:03013200000207C1
:0301330000016266
:03013400000FFFBA
:0301350000015076
:03013600000D08B1
:03013700000122A2
:03013800000201C1
:0301390000003093
:03013A00000901B8
:03013B00000204BB
:03013C0000003090
:03013D00000901B5
:03013E00000202BA
:03013F000000308D
:03014000000901B2
:03014100000C00AF
:0301420000002F8B
:030143000007D3DF
:03014400000B6B42
:03014500000210A5
:0301460000002294
:0301470000020EA5
:030148000000278D
:03014900000C5057
:03014A0000003979
:03014B0000079911
:03014C00000B4B5A
:03014D000002129B
:03014E000000307E
:03014F0000021497
:030150000000317B
:0301510000021396
:030152000006B3F1
:03015300000D108C
:0301540000003276
:03015500000C009B
:0301560000003373
:03015700000C7029
:030158000000396B
:03015900000C5047
:03015A0000003969
:03015B000002158A
:03015C0000003070
:03015D0000021687
:03015E000000316D
:03015F0000020299
:030160000000326A
:03016100000C008F
:030162000006B3E1
:0301630000020790
:0301640000003365
:03016500000C701B
:030166000000395D
:03016700000C5039
:030168000000395B
:03016900000C4047
:03016A0000003959
:03016B00000C0085
:03016C0000003957
:03016D00000C0083
:03016E00000C0082
:03016F00000AACD7
:03017000000C027E
:0301710000002F5C
:03017200000C0A74
:0301730000002A5F
:03017400000C007C
:030175000006B3CE
:030176000002077D
:0301770000003352
:03017800000C7008
:030179000000394A
:03017A00000C5026
:03017B0000003948
:03017C00000C4034
:03017D0000003946
:03017E00000C0072
:03017F0000003944
:03018000000C0070
:03018100000C006F
:03018200000ABFB1
:03018300000C026B
:0301840000002F49
:03018500000C0A61
:0301860000002A4C
:03018700000C0069
:0301880000002450
:030189000007D399
:03018A00000BA6C1
:03018B000002016E
:03018C0000003040
:03018D0000090165
:03018E0000021557
:03018F000000303D
:0301900000090162
:0301910000021653
:030192000000303A
:030193000009015F
:03019400000C1F3D
:0301750000002463
:030176000007D3AC
:03017700000B93E7
:0301780000020181
:0301790000003053
:03017A0000090178
:03017B000002156A
:03017C0000003050
:03017D0000090175
:03017E0000021666
:03017F000000304D
:0301800000090172
:03018100000C1F50
:03018200000D80ED
:0301830000002257
:0301840000020175
:0301850000003047
:030186000009016C
:0301870000020271
:0301880000003044
:0301890000090169
:03018A000002046C
:03018B0000003041
:03018C0000090166
:03018D000002EA83
:03018E0000071057
:03018F00000B91D1
:03019000000B84DD
:030191000007D391
:03019200000BB1AE
:03019300000C1D40
:030194000006D38F
:03019500000D80DA
:0301960000002244
:0301970000020162
@@ -414,73 +414,54 @@
:03019A000002025E
:03019B0000003031
:03019C0000090156
:03019D0000020459
:03019D0000021845
:03019E000000302E
:03019F0000090153
:0301A0000002EA70
:0301A10000071044
:0301A200000BA4AB
:0301A300000B97B7
:0301A4000007D37E
:0301A500000BC488
:0301A600000C1D2D
:0301A7000006D37C
:0301A800000D80C7
:0301A90000002231
:0301AA000002014F
:0301AB0000003021
:0301AC0000090146
:0301AD000002024B
:0301AE000000301E
:0301AF0000090143
:0301B00000021832
:0301B1000000301B
:0301B20000090140
:0301B30000021037
:0301B40000002E1A
:0301B500000C1C1F
:0301B6000006D36D
:0301B700000D80B8
:0301B80000002222
:0301B90000020140
:0301BA0000003012
:0301BB0000090137
:0301BC000002023C
:0301BD000000300F
:0301BE0000090134
:0301BF0000021724
:0301C0000000300C
:0301C10000090131
:0301C2000007D360
:0301C300000B8BA3
:0301A0000002104A
:0301A10000002E2D
:0301A200000C1C32
:0301A3000006D380
:0301A400000D80CB
:0301A50000002235
:0301A60000020153
:0301A70000003025
:0301A8000009014A
:0301A9000002024F
:0301AA0000003022
:0301AB0000090147
:0301AC0000021737
:0301AD000000301F
:0301AE0000090144
:0301AF000007D373
:0301B000000B78C9
:0301B100000C003F
:0301B20000002F1B
:0301B3000007D36F
:0301B400000B6BD2
:0301B500000B45F7
:0301B600000C0733
:0301B70000002F16
:0301B800000C0434
:0301B90000002122
:0301BA00000C0036
:0301BB0000091E1A
:0301BC00000C1024
:0301BD000000211E
:0301BE00000C082A
:0301BF0000091E16
:0301C000000C40F0
:0301C1000000211A
:0301C200000C101E
:0301C30000091E12
:0301C400000C002C
:0301C50000002F08
:0301C6000007D35C
:0301C700000B7EAC
:0301C800000B58D1
:0301C900000C0720
:0301CA0000002F03
:0301CB00000C0421
:0301CC000000210F
:0301CD00000C0023
:0301CE0000091E07
:0301CF00000C1011
:0301D0000000210B
:0301D100000C0817
:0301D20000091E03
:0301D300000C40DD
:0301D40000002107
:0301D500000C100B
:0301D60000091EFF
:0301D700000C0019
:0301D80000003AEA
:0301D900000C0116
:0301DA00000029F9
:0301DB00000C0015
:0301DC0000002FF1
:0301DD00000C20F3
:0301DE00000023FB
:0301DF00000A0013
:0301E000000ABF53
:0301E100000BE12F
:0301C50000002611
:0301C600000C0129
:0301C7000000290C
:0301C800000C0028
:0301C90000002F04
:0301CA00000C2006
:0301CB000000230E
:0301CC00000A0026
:0301CD00000AAC79
:0301CE00000BCE55
:00000001FF

View File

@@ -1,7 +1,7 @@
#
# $Id: PIC_TYPE_2.hex 11078 2013-04-11 16:52:37Z dima $
# $Id: PIC_TYPE_2.hex 7107 2009-05-18 12:35:20Z dima $
#
:03000000A5DA4836
:03000000A57A4896
:03000100C41C41DB
:030002000390392F
:0300030067967984
@@ -42,375 +42,298 @@
:03002600CFC9013E
:030027001652026C
:0300280064403001
:03002900A38901A7
:03002900A3290107
:03002A00704C40D7
:03002B00A47FFFB0
:03002C00C40165A7
:03002D00150C02AD
:03002E00743FFF1D
:03002F00A32150BA
:03003000C026B92E
:03003100A33D02EA
:03003200C01022D9
:03003300121C029A
:03003400C03D01CB
:030035001611623F
:0300360020120590
:0300370012503034
:0300380020A901FB
:030039006432042A
:03003A00A40030EF
:03003B0036590132
:03003C0036520237
:03003D002C8030E4
:03003E00D00901E5
:03003F00A3980083
:0300400020521437
:03004100724E708C
:03004200A44308CC
:03004300A46308AB
:0300440002D308DC
:03004500A4730899
:0300460002E03F96
:030047008008002E
:03004800022C0087
:03004900206039FB
:03004A00643038E7
:03004B00A50C07FA
:03004C00322D4012
:03004D002C8034D0
:03004E00D00C08CB
:03004F00A4A03832
:03005000CFE219E3
:03005100162E0761
:03005200C01020BB
:03005300604360A7
:0300540012236014
:03005500206360C5
:03005600643360B0
:03005700A5CC1025
:0300580036203817
:030059002C8219DD
:03005A00D00E07BE
:03005B00A561207C
:03005C00800C20F5
:03005D00C07180EF
:03005E00166E70AB
:03005F00743743B0
:03006000A65A702D
:03006100C01C02BE
:030062001CC1803E
:03006300E07E0735
:0300640002C6438E
:03006500200A73FB
:03002B00A41FFF10
:03002C00C011659B
:03002D001E1C0294
:03002E00C03FFFD1
:03002F0016115057
:030030002016B9DE
:03003100125D025B
:0300320020A022E9
:03003300643C0228
:03003400A3AD0178
:03003500365162DF
:030036003652053A
:030037002C8030EA
:03003800D00901EB
:03003900A33204EB
:03003A0020503023
:03003B0072490106
:03003C00A3E2023A
:03003D00A40030EC
:03003E0002D901E3
:03003F00A4180002
:0300400002E214C5
:03004100800E70BE
:030042000223088E
:030043002063082F
:030044006433081A
:03004500A4A30869
:0300460032203F26
:030047002C880002
:03004800D00C00D9
:03004900A4403997
:03004A00CFE038CC
:03004B00162C0769
:03004C00C01D4094
:03004D00604034DC
:03004E00122C0869
:03004F00206038F6
:03005000643219FE
:03005100A56E0792
:0300520036202035
:030053002C83609B
:03005400D0036076
:03005500A50360A0
:03005600800360C4
:03005700C07C105A
:03005800166038F7
:03005900743219E5
:03005A00A5FE07F9
:03005B00C01120B1
:03005C001CCC2099
:03005D00E07180CF
:03005E0002CE705F
:03005F00206743D4
:0300600090AA6BF8
:03006100205C021E
:03006200D2018048
:03006300D40E03B5
:0300640003D6437D
:03006500C1CA6E9F
:03006600022C0366
:0300670020618095
:03006800643E07EC
:03006900A6E643C5
:03006A00322A73C4
:03006B002C8C04D6
:03006C00D0018040
:03006D00A68E0755
:03006E00C0164376
:03006F00142A73DD
:03007000743C01DC
:03007100ACB038F8
:03007200206A728F
:0300730090AC1836
:03007400205038E1
:03007500D202199B
:03007600D40E0F96
:0300770003D02291
:03007800C04C0079
:030079000220382A
:03007A00C00200C1
:03007B00024E072B
:03007C0021DF027F
:03007D0003074333
:03007E00901A8352
:03007F00202C0032
:0300800003003149
:03008100901C12BE
:03008200204A9081
:0300830003020075
:03008400901E07C4
:03008500210F0345
:03008600E017433D
:03008700643A8C4C
:03008800ACBC000D
:0300890021003122
:03008A00024C180D
:03008B00E80A90F0
:03008C00743C00C1
:03008D00AB803114
:03008E00C50C1688
:03008F00039A9041
:0300900079903B29
:03009100A90E0FA6
:0300920020B08219
:03009300D0070390
:03009400038A9A42
:03009500219C0F9C
:03009600E07FFF09
:0300970034815B56
:03009800348102AE
:03009900348A9B0B
:03009A0034821B92
:03009B000300302F
:03009C00206E0FC4
:03009D0034803B71
:03009E00348C029D
:03009F0034803971
:0300A000348C009D
:0300A100D0503903
:0300A200031C80BC
:0300A300C00D0885
:0300A400032039FD
:0300A500033C0019
:0300A600C7003957
:0300A700039C4077
:0300A800C5003957
:0300A9000397D9E1
:0300AA00C04AA9A0
:0300AB00030C0043
:0300AC00C000266B
:0300AD0003102716
:0300AE0020402BC4
:0300AF000320200B
:0300B000C00C037E
:0300B10003302CED
:0300B200C70C2058
:0300B300039D802A
:0300B400C500255F
:0300B500039C2089
:0300B600C400245F
:0300B700039C00A7
:0300B800C400225F
:0300B900FFF2054E
:0300BA00165030AD
:0300BB00D2090166
:0300BC0003D20468
:0300BD00C0403010
:0300BE0002290113
:0300BF00C002027A
:0300C000150030F8
:0300C100024901F0
:0300C20021DC40FE
:0300C300030039FE
:0300C400901C018C
:0300C500202037C1
:0300C600030C60C8
:0300C7009012C8CC
:0300C800204AC704
:0300C900030C0025
:0300CA009010375C
:0300CB002066D9D3
:0300CC0090AAD027
:0300CD002056F9C1
:0300CE00D20B4D05
:0300CF00D40ACB85
:0300D00003D94011
:0300D100C1CC207F
:0300D20002219573
:0300D300C0064321
:0300D400024ADFFE
:0300D50021DC012A
:0300D6000301DF44
:0300D70090109BEB
:0300D800202703DB
:0300D900030ADF38
:0300DA009017D3A9
:0300DB00204B486F
:0300DC00030CFF13
:0300DD009010225E
:0300DE00210B2AC9
:0300DF0002421FBB
:0300E000C0390A1A
:0300E100084C20A8
:0300E20060312565
:0300E300AE66D333
:0300E400209AEA75
:0300E500AE8C20BE
:0300E600C00095C2
:0300E700AE86439F
:0300E800187AF291
:0300E900149AEF77
:0300EA00643C4033
:0300EB00B17125CB
:0300EC001A7C007B
:0300ED00C5002427
:0300EE00039B1A57
:0300EF00799217EC
:0300F000AEF0244B
:0300F10020BB1A17
:0300F200D00C40EF
:0300F30003810581
:0300F40021903D1B
:0300F500E07C00AC
:0300F6003480242F
:0300F70034821D33
:0300F80034803021
:0300F90034890146
:0300FA00030215E9
:0300FB0020603052
:0300FC0034890143
:0300FD0034820446
:0300FE003480301B
:0300FF0034890140
:03010000D05210CA
:03010100031024C4
:03010200C007F73C
:03010300032B0BC0
:03010400033C02B7
:03010500C70FFF22
:03010600039164FE
:03010700C50C0222
:0301080003915709
:03010900C1C1244D
:03010A00030B17CD
:03010B00C007D753
:03010C00031B17BB
:03010D00204C0182
:03010E00032FFFBD
:03010F00C00164C8
:03011000033C01AC
:03011100C70157CC
:0301120003912432
:03011300C50B1702
:030114000392173C
:03011500C40024FF
:03011600039B1731
:0301170020CC02F7
:03011800743D0132
:03011900B8316496
:03011A00C00C8096
:03011B000246F3A6
:03011C00C05125AA
:03011D00022205B6
:03011E002050303E
:03011F00D2090101
:03012000D40215F1
:0301210003D030D8
:0301220021D901DF
:03012300030204D0
:0301240090103008
:030125002029018D
:030126000307D3F9
:03012700901B48E2
:0301280020421062
:03012900030022AE
:03012A00901C50D6
:03012B00C01039C8
:03012C001507991B
:03012D00024B2C56
:03012E0021A212F9
:03012F0094803089
:0301300020221476
:0301310003A031F7
:0301320020621335
:03013300743032F3
:03013400B41C00F8
:03013500C9F033DB
:0301360016BC7084
:03013700C00039CC
:030138006B0C50FD
:03013900D20039B8
:03013A006D02153E
:03013B00D40030BD
:03013C0012BC00F2
:03013D00C80031C6
:03013E001AB202F0
:03013F0020B032BB
:03014000038C002D
:0301410020603308
:0301420002AC709C
:03014300C0403980
:03014400086C50F4
:03014500703039DE
:03014600B4AC4016
:03014700C00039BC
:03014800024C0066
:03014900B4E039E6
:03014A00C04C00A6
:03014B000AAC00FB
:03014C00C02AC204
:03014D00024C0061
:03014E0091702588
:03014F00C01C10C1
:0301500003E03D8C
:030151002069170B
:03015200643C0406
:03015300B570255F
:0301540037EC0085
:030155002C803DBE
:03015600B5491791
:03015700C60C02D1
:030158001500256A
:03015900743C08EB
:03015A00B6B03DFF
:03015B0021E91780
:03015C001AFC008A
:03015D0014F02675
:03015E00743C01ED
:03015F00B830298C
:03016000C04C2070
:0301610012402326
:03016200917A008F
:03016300C00B636B
:0301640002400056
:0301650020000077
:0301660094800082
:0301670020200055
:0301680002000092
:0301690003500040
:03016A00B83000AA
:03016B00CFF000D2
:03016C0019E00097
:03016D0016F00089
:03016E00C030009E
:03016F0008100075
:03017000743000E8
:03017100B7A00034
:03017200C01000BA
:0301730002400047
:0301740020000068
:0301750094800073
:0301760020200046
:0301770002000083
:0301780003500031
:03017900B830009B
:03017A00C00000C2
:03017B0018100059
:03017C00643000EC
:03017D006B000014
:03017E00B80000C6
:03017F00B8300095
:03018000C01000AC
:0301810012400029
:0301820091700079
:03018300369000B3
:03018400C01000A8
:030185001E6000F9
:0301860021B000A5
:030187000860000D
:03018800743000D0
:03018900A5D000FE
:03018A0002600010
:03018B00C0200091
:03018C00FFF00081
:03018D0016B000A9
:03018E00C020008E
:03018F0023A000AA
:03019000743000C8
:0301910012B000A9
:0301920020B0009A
:03019300038000E6
:03019400C4400064
:03019500039000D4
:03019600C40000A2
:03019700039000D2
:03019800C00000A4
:0301990002300031
:03019A00AC200096
:03019B00B9B000F8
:03006700C0018055
:03006800024E0342
:0300690021D6435A
:03006A00030A6E18
:03006B00901C01E5
:03006C0020203819
:03006D00030A6D16
:03006E00901C18CB
:03006F00204038F6
:030070000302196F
:03007100901E0FCF
:0300720021002248
:03007300024C003C
:03007400C0303861
:030075000842003E
:03007600603E03E6
:03007700A7AF022E
:030078002097438B
:03007900A7CA7E95
:03007A00C00C00B7
:03007B00A7C031EA
:03007C00187C12DB
:03007D00149A8250
:03007E00643C00DF
:03007F00AAB031F3
:030080001A7C18CF
:03008100C50A822B
:0300820003903BAD
:03008300799E0F54
:03008400A830821F
:0300850020B7039E
:03008600D00A8C11
:03008700038C0FD8
:03008800219FFFB6
:03008900E0715BC8
:03008A00348102BC
:03008B00348A8D27
:03008C0034821BA0
:03008D003480308C
:03008E00030E0F4F
:03008F0020603BB3
:03009000348C02AB
:030091003480397F
:03009200348C00AB
:030093003480397D
:03009400D05C80BD
:03009500031D0840
:03009600C000396E
:03009700032C0037
:03009800033039F9
:03009900C70C4051
:03009A0003903997
:03009B00C507D9BD
:03009C00039A9B29
:03009D00C1CC00D3
:03009E0003002636
:03009F00C0002777
:0300A00003102B1F
:0300A100204020DC
:0300A200032C0329
:0300A300C0002C6E
:0300A400033C20FA
:0300A500C70D8004
:0300A6000390259F
:0300A700C50C2065
:0300A8000390249E
:0300A900C40C0084
:0300AA000390229E
:0300AB0020C2056B
:0300AC007430307D
:0300AD00B1790125
:0300AE00C0020489
:0300AF00024030DC
:0300B000C0590133
:0300B10002220226
:0300B200205030AB
:0300B300D209016E
:0300B400D40C4029
:0300B50003D0393C
:0300B60021D6D977
:0300B700030ABB7E
:0300B8009016F9A6
:0300B900202B38C1
:0300BA00030AB680
:0300BB0090194059
:0300BC00204C20B5
:0300BD00030195A7
:0300BE0090164356
:0300BF00C01ACA9A
:0300C000150C011B
:0300C1000241DF1A
:0300C20021A09BDF
:0300C3009427037C
:0300C400202ACA25
:0300C50003A7D3BB
:0300C600206B3379
:0300C700743CFF87
:0300C800AD502216
:0300C900C9FB155B
:0300CA0016B21F4C
:0300CB00C0090A5F
:0300CC006B0C209A
:0300CD00D2012538
:0300CE006D06D3E9
:0300CF00D40AD57B
:0300D00012BC203F
:0300D100C80095CF
:0300D2001AB64318
:0300D30020BADD73
:0300D400038ADAC2
:0300D500206C405C
:0300D60002A1255F
:0300D700C04C001A
:0300D80008602499
:0300D900703B0574
:0300DA00ADE2177D
:0300DB00C000243E
:0300DC00024B05CF
:0300DD00AE2C4006
:0300DE00C0410519
:0300DF000AA03D37
:0300E000C02C0031
:0300E100024024B6
:0300E20091721DFB
:0300E300C010301A
:0300E40003E9012C
:0300E50020621581
:0300E60064303053
:0300E700AEB901AE
:0300E80037E204F8
:0300E9002C803038
:0300EA00AE8901DB
:0300EB00C602103A
:0300EC00150024D8
:0300ED007437F76E
:0300EE00AFFAF670
:0300EF0021EC02FF
:0300F0001AFFFFF5
:0300F10014F164A3
:0300F200743C0259
:0300F300B1715791
:0300F400C04124E4
:0300F500124B02A9
:0300F6009177D728
:0300F700C00B0239
:0300F800024C01B6
:0300F900200FFFD6
:0300FA00942164EA
:0300FB00202C01B5
:0300FC00020157A7
:0300FD0003512488
:0300FE00B17B02D1
:0300FF00CFF21726
:0301000019E024DF
:0301010016FB02E8
:03010200C03C02FC
:03010300081D01D3
:03010400743164EF
:03010500B0EC80DB
:03010600C016F32D
:030107000241258D
:03010800200205CD
:030109009420300F
:03010A00202901A8
:03010B00020215D8
:03010C000350306D
:03010D00B17901C4
:03010E00C0020428
:03010F0018103095
:030110006439014E
:030111006B07D3A6
:03011200B14B33BB
:03011300B17210B6
:03011400C01022F6
:03011500124C5039
:03011600917039AC
:030117003697997F
:03011800C01B17F2
:030119001E621251
:03011A0021B030E1
:03011B0008621463
:03011C007430310B
:03011D00A57213B5
:03011E000260324A
:03011F00C02C00F1
:03012000FFF033BA
:0301210016BC7099
:03012200C02039C1
:0301230023AC50BA
:03012400743039FB
:0301250012B215FE
:0301260020B030D6
:03012700038C0046
:03012800C440319F
:030129000392023C
:03012A00C40032DC
:03012B00039C0032
:03012C00C00033DD
:03012D00023C7021
:03012E00AB4039AA
:03012F00B2FC50CF
:0301300000003993
:03013100000C407F
:0301320000003991
:03013300000C00BD
:030134000000398F
:03013500000C00BB
:03013600000C00BA
:03013700000AB407
:03013800000C04B4
:030139000000259E
:03013A00000C00B6
:03013B0000003D84
:03013C00000917A0
:03013D00000C02B1
:03013E0000002599
:03013F00000C08A9
:0301400000003D7F
:030141000009179B
:03014200000C06A8
:0301430000002594
:03014400000C109C
:0301450000003D7A
:0301460000091796
:03014700000C00A9
:030148000000268E
:03014900000C01A6
:03014A0000002989
:03014B00000C2085
:03014C000000238D
:03014D00000A00A5
:03014E00000B4E55
:00000001FF

Some files were not shown because too many files have changed in this diff Show More