Compare commits
71 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e0aa64075 | ||
|
|
ecc4999070 | ||
|
|
66edd67565 | ||
|
|
897cbb01de | ||
|
|
f9e4bf52c2 | ||
|
|
44a5add969 | ||
|
|
d18ec7f3b9 | ||
|
|
f69326bb66 | ||
|
|
c95385bb06 | ||
|
|
76468854ed | ||
|
|
2242c5394b | ||
|
|
62c5402a24 | ||
|
|
b222cfeb5d | ||
|
|
bd373e5075 | ||
|
|
49d2e93245 | ||
|
|
c573e5eaf5 | ||
|
|
7559b61e54 | ||
|
|
f4cffb0c1a | ||
|
|
42c0efb700 | ||
|
|
4afe8d0213 | ||
|
|
ae9d3a0bdc | ||
|
|
d635b1ef61 | ||
|
|
6527164a02 | ||
|
|
2f55744b15 | ||
|
|
5ddb6535f7 | ||
|
|
172ddb07b9 | ||
|
|
94a00c0f00 | ||
|
|
47fbd9bcc3 | ||
|
|
1a9b8662ad | ||
|
|
c3f65d39fa | ||
|
|
c36b6cd738 | ||
|
|
14f64038b0 | ||
|
|
a135f4e817 | ||
|
|
1e8c9fb797 | ||
|
|
0893461985 | ||
|
|
8edbfa881e | ||
|
|
43412bc513 | ||
|
|
1cf2b86e75 | ||
|
|
380ceed257 | ||
|
|
3408c774ce | ||
|
|
2de79e8905 | ||
|
|
99f1c099ec | ||
|
|
136ab72d6c | ||
|
|
e667e47418 | ||
|
|
90c209f77b | ||
|
|
2ecf474a07 | ||
|
|
2fefa9dd60 | ||
|
|
d624adb358 | ||
|
|
40942e2a43 | ||
|
|
78c92b52ed | ||
|
|
1bf7ebc42f | ||
|
|
7a275dc70b | ||
|
|
9fb13e2f6c | ||
|
|
fcbde772c4 | ||
|
|
2bc2ebd1de | ||
|
|
0f8559b045 | ||
|
|
d6075a4c78 | ||
|
|
c6e5ab448c | ||
|
|
8ff6810740 | ||
|
|
f3262ae381 | ||
|
|
c3c891abdd | ||
|
|
2fb5d7d6d7 | ||
|
|
08ce93306d | ||
|
|
dac1d88399 | ||
|
|
5218e90962 | ||
|
|
da2406db64 | ||
|
|
0b52fb24a0 | ||
|
|
2f880acd10 | ||
|
|
950a3f2486 | ||
|
|
2405c809e7 | ||
|
|
eb1c6cbeed |
50
.gitignore
vendored
50
.gitignore
vendored
@@ -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
|
||||
35
Makefile
35
Makefile
@@ -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
|
||||
|
||||
@@ -196,12 +212,11 @@ test:
|
||||
docs: $(GENERATED_DOCS)
|
||||
|
||||
README.html: README
|
||||
date=`stat -c "%y" $<`
|
||||
$(ASCIIDOC_CMD) -a revdate="$$date" -o $@ $<
|
||||
$(ASCIIDOC_CMD) -o $@ $<
|
||||
|
||||
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:
|
||||
|
||||
513
README
513
README
@@ -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
|
||||
@@ -248,15 +229,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 +417,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,188 +472,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)
|
||||
|
||||
Deprecated. See dahdi.<<_auto_assign_spans,auto_assign_spans>> above.
|
||||
|
||||
Originally had a somewhat similar (but xpp-specific and more limited)
|
||||
role to auto_assign_spans. For backward compatibility this variable is
|
||||
still kept, but its value is unused. Astribanks will auto-register
|
||||
with dahdi if auto_assign_spans is not set.
|
||||
|
||||
==== 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
|
||||
@@ -656,14 +490,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?
|
||||
@@ -706,7 +535,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.
|
||||
@@ -726,81 +554,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.
|
||||
@@ -888,174 +641,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 the non-channel 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. The files in this class `ctl`, `timer`,
|
||||
`channel`, `pseudo` and (if exists) `transcode`.
|
||||
|
||||
|
||||
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/registration_time
|
||||
The time at which the device registered with the DAHDI core. Example
|
||||
value: "0005634136.941901429".
|
||||
|
||||
===== /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
|
||||
@@ -1133,7 +718,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:
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
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
40
build_tools/genudevrules
Executable 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
|
||||
@@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
# This is a helper script intended to be called from
|
||||
# drivers/dahdi/firmware/Makefile to install the different firmware version.
|
||||
|
||||
FIRMWARE_PATTERN=$1
|
||||
FIRMWARE_VERSION=$2
|
||||
DESTDIR=$3
|
||||
target="$DESTDIR/lib/firmware"
|
||||
|
||||
if ! test -f $target/.${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}; then
|
||||
echo "Installing ${FIRMWARE_PATTERN}.bin to $target"
|
||||
tar --no-same-owner -xf ${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}.tar.gz || exit 1
|
||||
install -m 644 ${FIRMWARE_PATTERN}.bin $target || exit 1
|
||||
rm -rf $target/.${FIRMWARE_PATTERN}-*
|
||||
touch $target/.${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}
|
||||
# Remove the .bin file so that if the version is reverted, it will not
|
||||
# be installed with a non-matching ${FIRMARE_VERSION} file.
|
||||
rm ${FIRMWARE_PATTERN}.bin
|
||||
else
|
||||
echo "Firmware ${FIRMWARE_PATTERN}.bin is already installed with required version ${FIRMWARE_VERSION}"
|
||||
fi
|
||||
@@ -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
|
||||
|
||||
@@ -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'"
|
||||
@@ -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
|
||||
|
||||
@@ -7,35 +7,10 @@ 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/
|
||||
@@ -63,7 +38,7 @@ obj-m += $(DAHDI_MODULES_EXTRA)
|
||||
# well:
|
||||
ifneq (,$(wildcard $(src)/../staging/echo/echo.c))
|
||||
obj-m += dahdi_echocan_oslec.o
|
||||
obj-m += ../staging/echo/echo.o
|
||||
obj-m += ../staging/echo/
|
||||
endif
|
||||
|
||||
CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src)
|
||||
@@ -102,7 +77,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
6
drivers/dahdi/Makefile
Normal 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
@@ -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();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
@@ -201,9 +199,7 @@ static void dahdi_dynamic_sendmessage(struct dahdi_dynamic *d)
|
||||
static void __dahdi_dynamic_run(void)
|
||||
{
|
||||
struct dahdi_dynamic *d;
|
||||
#ifdef ENABLE_TASKLETS
|
||||
struct dahdi_dynamic_driver *drv;
|
||||
#endif
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(d, &dspan_list, list) {
|
||||
@@ -212,25 +208,12 @@ static void __dahdi_dynamic_run(void)
|
||||
dahdi_dynamic_sendmessage(d);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_TASKLETS
|
||||
list_for_each_entry_rcu(drv, &driver_list, list) {
|
||||
/* Flush any traffic still pending in the driver */
|
||||
if (drv->flush) {
|
||||
drv->flush();
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* 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);
|
||||
#endif
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
@@ -402,18 +385,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)
|
||||
@@ -472,25 +469,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);
|
||||
@@ -599,8 +578,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);
|
||||
@@ -625,17 +604,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",
|
||||
@@ -683,12 +657,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);
|
||||
@@ -729,20 +699,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)
|
||||
@@ -805,17 +761,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);
|
||||
}
|
||||
}
|
||||
@@ -859,13 +817,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;
|
||||
@@ -875,31 +830,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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -266,7 +271,6 @@ static void ztdeth_destroy(struct dahdi_dynamic *dyn)
|
||||
struct ztdeth *z = dyn->pvt;
|
||||
unsigned long flags;
|
||||
struct ztdeth *prev=NULL, *cur;
|
||||
|
||||
spin_lock_irqsave(&zlock, flags);
|
||||
cur = zdevs;
|
||||
while(cur) {
|
||||
@@ -281,10 +285,7 @@ static void ztdeth_destroy(struct dahdi_dynamic *dyn)
|
||||
cur = cur->next;
|
||||
}
|
||||
spin_unlock_irqrestore(&zlock, flags);
|
||||
|
||||
if (cur == z) { /* Successfully removed */
|
||||
dyn->pvt = NULL;
|
||||
dev_put(z->dev);
|
||||
printk(KERN_INFO "TDMoE: Removed interface for %s\n", z->span->name);
|
||||
kfree(z);
|
||||
}
|
||||
@@ -410,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");
|
||||
|
||||
@@ -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, ðmf_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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 {\
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -168,9 +168,8 @@ static void dtc_release(struct dahdi_transcoder_channel *chan)
|
||||
BUG_ON(!chan);
|
||||
if (chan->parent && chan->parent->release) {
|
||||
chan->parent->release(chan);
|
||||
} else {
|
||||
dahdi_tc_clear_busy(chan);
|
||||
}
|
||||
dahdi_tc_clear_busy(chan);
|
||||
}
|
||||
|
||||
static int dahdi_tc_release(struct inode *inode, struct file *file)
|
||||
|
||||
@@ -1063,23 +1063,12 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
|
||||
|
||||
used = pvc_is_used(pvc);
|
||||
|
||||
if (type == ARPHRD_ETHER) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
|
||||
dev = alloc_netdev(sizeof(struct net_device_stats),
|
||||
"pvceth%d", NET_NAME_UNKNOWN, ether_setup);
|
||||
#else
|
||||
if (type == ARPHRD_ETHER)
|
||||
dev = alloc_netdev(sizeof(struct net_device_stats),
|
||||
"pvceth%d", ether_setup);
|
||||
#endif
|
||||
} else {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
|
||||
dev = alloc_netdev(sizeof(struct net_device_stats),
|
||||
"pvc%d", NET_NAME_UNKNOWN, dlci_setup);
|
||||
#else
|
||||
else
|
||||
dev = alloc_netdev(sizeof(struct net_device_stats),
|
||||
"pvc%d", dlci_setup);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!dev) {
|
||||
printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
|
||||
|
||||
@@ -282,12 +282,7 @@ static void hdlc_setup(struct net_device *dev)
|
||||
struct net_device *alloc_hdlcdev(void *priv)
|
||||
{
|
||||
struct net_device *dev;
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
|
||||
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d",
|
||||
NET_NAME_UNKNOWN, hdlc_setup);
|
||||
#else
|
||||
dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup);
|
||||
#endif
|
||||
if (dev)
|
||||
dev_to_hdlc(dev)->priv = priv;
|
||||
return dev;
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <net/syncppp.h>
|
||||
|
||||
|
||||
@@ -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,29 +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:=7a001e
|
||||
TE134_VERSION:=780017
|
||||
TE435_VERSION:=13001e
|
||||
TE436_VERSION:=10017
|
||||
A8A_VERSION:=1d0017
|
||||
A8B_VERSION:=1f001e
|
||||
A4A_VERSION:=a0017
|
||||
A4B_VERSION:=d001e
|
||||
VPMOCT032_VERSION:=1.11.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 FIRMWARE-TE436
|
||||
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
|
||||
@@ -53,30 +40,17 @@ 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-TE436=dahdi-fw-te436-$(TE436_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)
|
||||
@@ -84,8 +58,6 @@ OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032.o)
|
||||
# Force usage of wget, for now
|
||||
DOWNLOAD=wget
|
||||
WGET=wget
|
||||
INSTALL_FIRMWARE=../../../build_tools/install_firmware
|
||||
RUN_INST=$(INSTALL_FIRMWARE) $(1) $(2) $(DESTDIR)
|
||||
|
||||
# If "fetch" is used, --continue is not a valid option.
|
||||
ifeq ($(WGET),wget)
|
||||
@@ -111,6 +83,7 @@ dahdi-fw-%.tar.gz:
|
||||
echo "Attempting to download $@"; \
|
||||
if test ! -f $@; then $(DOWNLOAD) $(WGET_ARGS) $(FIRMWARE_URL)/$@; fi; \
|
||||
if test ! -f $@; then exit 1; fi; \
|
||||
(cat $@ | gzip -d | tar --no-same-owner -xf -) \
|
||||
fi
|
||||
|
||||
firmware-loaders: $(FWLOADERS)
|
||||
@@ -129,22 +102,61 @@ $(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)
|
||||
@$(call RUN_INST,dahdi-fw-oct6114-032,$(OCT6114_032_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-oct6114-064,$(OCT6114_064_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-oct6114-128,$(OCT6114_128_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-oct6114-256,$(OCT6114_256_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-tc400m,$(TC400M_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-hx8,$(HX8_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-vpmoct032,$(VPMOCT032_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-te820,$(WCT820_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-te133,$(TE133_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-te134,$(TE134_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-te435,$(TE435_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-te436,$(TE436_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-a8a,$(A8A_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-a8b,$(A8B_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-a4a,$(A4A_VERSION))
|
||||
@$(call RUN_INST,dahdi-fw-a4b,$(A4B_VERSION))
|
||||
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
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION)
|
||||
@install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-oct6114-064.bin is already installed with required version $(OCT6114_064_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-oct6114-128.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION)
|
||||
@install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION)
|
||||
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-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
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION)
|
||||
@install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-tc400m.bin is already installed with required version $(TC400M_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-$(HX8_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-$(HX8_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-hx8.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-hx8.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-$(HX8_VERSION)
|
||||
@install -m 644 dahdi-fw-hx8.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-$(HX8_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-hx8.bin is already installed with required version $(HX8_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-vpmoct032.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-vpmoct032.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION)
|
||||
@install -m 644 dahdi-fw-vpmoct032.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-vpmoct032.bin is already installed with required version $(VPMOCT032_VERSION)"
|
||||
endif
|
||||
|
||||
# Uninstall any installed dahdi firmware images from hotplug firmware directories
|
||||
hotplug-uninstall:
|
||||
@@ -163,11 +175,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
|
||||
@@ -178,11 +185,6 @@ 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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -129,7 +129,7 @@ $Octasic_Revision: 16 $
|
||||
/***************************** TYPES ***************************************/
|
||||
|
||||
/*Change this type if your platform uses 64bits semaphores/locks */
|
||||
typedef void* tOCT6100_USER_SERIAL_OBJECT;
|
||||
typedef UINT32 tOCT6100_USER_SERIAL_OBJECT;
|
||||
|
||||
typedef struct _OCT6100_GET_TIME_
|
||||
{
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -1,209 +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)
|
||||
{
|
||||
struct oct612x_context *context = f_pCreate->pProcessContext;
|
||||
struct mutex *lock = kzalloc(sizeof(*lock), GFP_KERNEL);
|
||||
if (!lock) {
|
||||
dev_err(context->dev, "Out of memory in %s.\n", __func__);
|
||||
return cOCT6100_ERR_BASE;
|
||||
}
|
||||
mutex_init(lock);
|
||||
f_pCreate->ulSerialObjHndl = lock;
|
||||
return cOCT6100_ERR_OK;
|
||||
}
|
||||
|
||||
UINT32 Oct6100UserDestroySerializeObject(
|
||||
tPOCT6100_DESTROY_SERIALIZE_OBJECT f_pDestroy)
|
||||
{
|
||||
struct mutex *lock = f_pDestroy->ulSerialObjHndl;
|
||||
kfree(lock);
|
||||
return cOCT6100_ERR_OK;
|
||||
}
|
||||
|
||||
UINT32 Oct6100UserSeizeSerializeObject(
|
||||
tPOCT6100_SEIZE_SERIALIZE_OBJECT f_pSeize)
|
||||
{
|
||||
struct mutex *lock = f_pSeize->ulSerialObjHndl;
|
||||
mutex_lock(lock);
|
||||
return cOCT6100_ERR_OK;
|
||||
}
|
||||
|
||||
UINT32 Oct6100UserReleaseSerializeObject(
|
||||
tPOCT6100_RELEASE_SERIALIZE_OBJECT f_pRelease)
|
||||
{
|
||||
struct mutex *lock = f_pRelease->ulSerialObjHndl;
|
||||
mutex_unlock(lock);
|
||||
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");
|
||||
@@ -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__ */
|
||||
@@ -51,8 +51,6 @@ With driver: 303826 (1.5 %)
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
@@ -148,7 +146,6 @@ struct encdec
|
||||
|
||||
struct pciradio {
|
||||
struct pci_dev *dev;
|
||||
struct dahdi_device *ddev;
|
||||
struct dahdi_span span;
|
||||
unsigned char ios;
|
||||
int usecount;
|
||||
@@ -482,6 +479,8 @@ static void rbi_out(struct pciradio *rad, int n, unsigned char *rbicmd)
|
||||
{
|
||||
unsigned long flags;
|
||||
int x;
|
||||
DECLARE_WAIT_QUEUE_HEAD(mywait);
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
@@ -489,8 +488,7 @@ int x;
|
||||
x = rad->remote_locked || (__pciradio_getcreg(rad,0xc) & 2);
|
||||
if (!x) rad->remote_locked = 1;
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
if (x)
|
||||
msleep_interruptible(20);
|
||||
if (x) interruptible_sleep_on_timeout(&mywait,2);
|
||||
else break;
|
||||
}
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
@@ -527,6 +525,7 @@ static void mx828_command(struct pciradio *rad,int channel, unsigned char comman
|
||||
|
||||
static void mx828_command_wait(struct pciradio *rad,int channel, unsigned char command, unsigned char *byte1, unsigned char *byte2)
|
||||
{
|
||||
DECLARE_WAIT_QUEUE_HEAD(mywait);
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
@@ -534,7 +533,7 @@ unsigned long flags;
|
||||
while(rad->encdec.state)
|
||||
{
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
msleep_interruptible(20);
|
||||
interruptible_sleep_on_timeout(&mywait,2);
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
}
|
||||
rad->encdec.lastcmd = jiffies + 1000;
|
||||
@@ -966,6 +965,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
} stack;
|
||||
|
||||
struct pciradio *rad = chan->pvt;
|
||||
DECLARE_WAIT_QUEUE_HEAD(mywait);
|
||||
|
||||
switch (cmd) {
|
||||
case DAHDI_RADIO_GETPARAM:
|
||||
@@ -1253,7 +1253,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
__pciradio_setcreg(rad,8,byte2);
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
if (i || (jiffies < rad->lastremcmd + 10))
|
||||
msleep_interruptible(100);
|
||||
interruptible_sleep_on_timeout(&mywait,10);
|
||||
rad->lastremcmd = jiffies;
|
||||
rbi_out(rad,chan->chanpos - 1,(unsigned char *)&stack.p.data);
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
@@ -1268,8 +1268,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
x = rad->remote_locked || (__pciradio_getcreg(rad,0xc) & 2);
|
||||
if (!x) rad->remote_locked = 1;
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
if (x)
|
||||
msleep_interruptible(20);
|
||||
if (x) interruptible_sleep_on_timeout(&mywait,2);
|
||||
else break;
|
||||
}
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
@@ -1286,14 +1285,14 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
__pciradio_setcreg(rad,8,byte2);
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
if (byte1 != byte2)
|
||||
msleep_interruptible(30);
|
||||
interruptible_sleep_on_timeout(&mywait,3);
|
||||
while (jiffies < rad->lastremcmd + 10)
|
||||
msleep_interruptible(100);
|
||||
interruptible_sleep_on_timeout(&mywait,10);
|
||||
rad->lastremcmd = jiffies;
|
||||
for(;;)
|
||||
{
|
||||
if (!(__pciradio_getcreg(rad,0xc) & 2)) break;
|
||||
msleep_interruptible(20);
|
||||
interruptible_sleep_on_timeout(&mywait,2);
|
||||
}
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
/* enable and address async serializer */
|
||||
@@ -1315,7 +1314,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
(!strchr((char *)rad->rxbuf,'\r'))))
|
||||
{
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
msleep_interruptible(20);
|
||||
interruptible_sleep_on_timeout(&mywait,2);
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
continue;
|
||||
}
|
||||
@@ -1335,7 +1334,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
while(rad->txlen && (rad->txindex < rad->txlen))
|
||||
{
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
msleep_interruptible(20);
|
||||
interruptible_sleep_on_timeout(&mywait,2);
|
||||
spin_lock_irqsave(&rad->lock,flags);
|
||||
}
|
||||
/* disable and un-address async serializer */
|
||||
@@ -1344,7 +1343,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
|
||||
rad->remote_locked = 0;
|
||||
spin_unlock_irqrestore(&rad->lock,flags);
|
||||
if (rad->remmode[chan->chanpos - 1] == DAHDI_RADPAR_REM_SERIAL_ASCII)
|
||||
msleep_interruptible(1000);
|
||||
interruptible_sleep_on_timeout(&mywait,100);
|
||||
if (copy_to_user((__user void *) data, &stack.p, sizeof(stack.p))) return -EFAULT;
|
||||
return 0;
|
||||
default:
|
||||
@@ -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,14 +1777,13 @@ 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;
|
||||
|
||||
}
|
||||
|
||||
if (request_irq(pdev->irq, pciradio_interrupt,
|
||||
IRQF_SHARED, "pciradio", rad)) {
|
||||
if (request_irq(pdev->irq, pciradio_interrupt, DAHDI_IRQ_SHARED, "pciradio", rad)) {
|
||||
printk(KERN_NOTICE "pciradio: Unable to request IRQ %d\n", pdev->irq);
|
||||
if (rad->freeregion)
|
||||
release_region(rad->ioaddr, 0xff);
|
||||
@@ -1812,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);
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
#define NEED_PCI_IDS
|
||||
@@ -98,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 */
|
||||
@@ -254,6 +252,16 @@ static int tor2_chanconfig(struct file *file,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tor2_open(struct dahdi_chan *chan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tor2_close(struct dahdi_chan *chan)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dahdi_span_ops tor2_span_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.spanconfig = tor2_spanconfig,
|
||||
@@ -262,6 +270,8 @@ static const struct dahdi_span_ops tor2_span_ops = {
|
||||
.shutdown = tor2_shutdown,
|
||||
.rbsbits = tor2_rbsbits,
|
||||
.maint = tor2_maint,
|
||||
.open = tor2_open,
|
||||
.close = tor2_close,
|
||||
.ioctl = tor2_ioctl,
|
||||
};
|
||||
|
||||
@@ -275,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;
|
||||
@@ -308,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 */
|
||||
|
||||
@@ -340,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)
|
||||
@@ -355,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);
|
||||
}
|
||||
|
||||
@@ -543,7 +551,7 @@ static int __devinit tor2_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||
for (x = 0; x < 256; x++)
|
||||
writel(0x7f7f7f7f, &tor->mem32[x]);
|
||||
|
||||
if (request_irq(tor->irq, tor2_intr, IRQF_SHARED, "tor2", tor)) {
|
||||
if (request_irq(tor->irq, tor2_intr, DAHDI_IRQ_SHARED_DISABLED, "tor2", tor)) {
|
||||
printk(KERN_ERR "Unable to request tormenta IRQ %d\n", tor->irq);
|
||||
goto err_out_release_all;
|
||||
}
|
||||
@@ -623,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)
|
||||
@@ -632,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);
|
||||
@@ -1200,7 +1213,6 @@ DAHDI_IRQ_HANDLER(tor2_intr)
|
||||
unsigned char c, rxc;
|
||||
unsigned char abits, bbits;
|
||||
struct tor2 *tor = (struct tor2 *) dev_id;
|
||||
unsigned long flags;
|
||||
|
||||
/* make sure its a real interrupt for us */
|
||||
if (!(readb(&tor->mem8[STATREG]) & INTACTIVE)) /* if not, just return */
|
||||
@@ -1208,8 +1220,6 @@ DAHDI_IRQ_HANDLER(tor2_intr)
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if (tor->cardtype == TYPE_E1) {
|
||||
/* set outbit, interrupt enable, and ack interrupt */
|
||||
writeb(OUTBIT | INTENA | INTACK | E1DIV | tor->master,
|
||||
@@ -1507,8 +1517,6 @@ DAHDI_IRQ_HANDLER(tor2_intr)
|
||||
else
|
||||
/* clear OUTBIT and enable interrupts */
|
||||
writeb(INTENA | tor->master, &tor->mem8[CTLREG]);
|
||||
|
||||
local_irq_restore(flags);
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#else
|
||||
#include <asm/semaphore.h>
|
||||
#endif
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
#include <dahdi/user.h>
|
||||
@@ -127,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);
|
||||
|
||||
6
drivers/dahdi/voicebus/Makefile
Normal file
6
drivers/dahdi/voicebus/Makefile
Normal 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
|
||||
@@ -1885,7 +1885,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, IRQF_SHARED,
|
||||
retval = request_irq(vb->pdev->irq, vb_isr, DAHDI_IRQ_SHARED,
|
||||
board_name, vb);
|
||||
if (retval) {
|
||||
dev_warn(&vb->pdev->dev, "Failed to request interrupt line.\n");
|
||||
@@ -2030,7 +2030,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -207,13 +206,7 @@ int vb_net_register(struct voicebus *vb, const char *board_name)
|
||||
struct voicebus_netdev_priv *priv;
|
||||
const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
|
||||
netdev = alloc_netdev(sizeof(*priv), board_name,
|
||||
NET_NAME_UNKNOWN, ether_setup);
|
||||
#else
|
||||
netdev = alloc_netdev(sizeof(*priv), board_name, ether_setup);
|
||||
#endif
|
||||
|
||||
if (!netdev)
|
||||
return -ENOMEM;
|
||||
priv = netdev_priv(netdev);
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "voicebus/vpmoct.h"
|
||||
#include "linux/firmware.h"
|
||||
@@ -73,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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -39,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
7
drivers/dahdi/wcb4xxp/Makefile
Normal file
7
drivers/dahdi/wcb4xxp/Makefile
Normal 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
|
||||
@@ -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.
|
||||
*
|
||||
*/
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <linux/timer.h> /* timer_struct */
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -91,7 +90,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;
|
||||
@@ -141,7 +139,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);
|
||||
@@ -1199,6 +1197,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)
|
||||
@@ -1226,6 +1225,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!
|
||||
@@ -1243,8 +1249,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;
|
||||
}
|
||||
@@ -1297,9 +1302,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)
|
||||
{
|
||||
@@ -1313,15 +1315,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. */
|
||||
@@ -1335,14 +1332,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()) {
|
||||
@@ -1365,9 +1355,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;
|
||||
|
||||
@@ -1451,7 +1441,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;
|
||||
}
|
||||
@@ -1473,17 +1462,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 */
|
||||
@@ -1498,24 +1484,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
|
||||
*/
|
||||
@@ -1526,16 +1494,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. */
|
||||
@@ -1566,13 +1528,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",
|
||||
@@ -1590,6 +1548,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.
|
||||
@@ -1622,6 +1591,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1878,10 +1849,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);
|
||||
@@ -2369,10 +2340,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. */
|
||||
@@ -2430,7 +2397,7 @@ b4xxp_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _b4xxp_open(struct dahdi_chan *chan)
|
||||
static int b4xxp_open(struct dahdi_chan *chan)
|
||||
{
|
||||
struct b4xxp *b4 = chan->pvt;
|
||||
struct b4xxp_span *bspan = &b4->spans[chan->span->offset];
|
||||
@@ -2444,15 +2411,6 @@ static int _b4xxp_open(struct dahdi_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b4xxp_open(struct dahdi_chan *chan)
|
||||
{
|
||||
unsigned long flags;
|
||||
int res;
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
res = _b4xxp_open(chan);
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int b4xxp_close(struct dahdi_chan *chan)
|
||||
{
|
||||
@@ -2516,9 +2474,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;
|
||||
@@ -2536,6 +2493,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 */
|
||||
@@ -2572,7 +2534,6 @@ DAHDI_IRQ_HANDLER(b4xxp_interrupt)
|
||||
{
|
||||
struct b4xxp *b4 = dev_id;
|
||||
unsigned char status;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
/* Make sure it's really for us */
|
||||
@@ -2586,8 +2547,6 @@ DAHDI_IRQ_HANDLER(b4xxp_interrupt)
|
||||
* That way if we get behind, we don't lose anything.
|
||||
* We don't actually do any processing here, we simply flag the bottom-half to do the heavy lifting.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
if (status & V_FR_IRQSTA) {
|
||||
b4->fifo_irqstatus[0] |= __pci_in8(b4, R_IRQ_FIFO_BL0);
|
||||
b4->fifo_irqstatus[1] |= __pci_in8(b4, R_IRQ_FIFO_BL1);
|
||||
@@ -2623,8 +2582,6 @@ DAHDI_IRQ_HANDLER(b4xxp_interrupt)
|
||||
/* tasklet_hi_schedule(&b4->b4xxp_tlet); */
|
||||
b4xxp_bottom_half((unsigned long)b4);
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
|
||||
@@ -2956,7 +2913,7 @@ static int __devinit b4xx_probe(struct pci_dev *pdev, const struct pci_device_id
|
||||
|
||||
create_sysfs_files(b4);
|
||||
|
||||
if (request_irq(pdev->irq, b4xxp_interrupt, IRQF_SHARED, "b4xxp", b4)) {
|
||||
if (request_irq(pdev->irq, b4xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "b4xxp", b4)) {
|
||||
dev_err(&b4->pdev->dev, "Unable to request IRQ %d\n",
|
||||
pdev->irq);
|
||||
ret = -EIO;
|
||||
@@ -2972,27 +2929,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3028,7 +2972,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);
|
||||
@@ -3049,8 +2996,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:
|
||||
@@ -3065,11 +3010,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);
|
||||
@@ -3084,8 +3032,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);
|
||||
}
|
||||
|
||||
@@ -3167,7 +3113,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");
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <linux/pci.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -136,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;
|
||||
@@ -570,7 +568,7 @@ static inline struct wcfxo *wcfxo_from_span(struct dahdi_span *span)
|
||||
return container_of(span, struct wcfxo, span);
|
||||
}
|
||||
|
||||
static int _wcfxo_open(struct dahdi_chan *chan)
|
||||
static int wcfxo_open(struct dahdi_chan *chan)
|
||||
{
|
||||
struct wcfxo *wc = chan->pvt;
|
||||
if (wc->dead)
|
||||
@@ -579,16 +577,6 @@ static int _wcfxo_open(struct dahdi_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wcfxo_open(struct dahdi_chan *chan)
|
||||
{
|
||||
int res;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
res = _wcfxo_open(chan);
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int wcfxo_watchdog(struct dahdi_span *span, int event)
|
||||
{
|
||||
printk(KERN_INFO "FXO: Restarting DMA\n");
|
||||
@@ -659,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
|
||||
@@ -685,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;
|
||||
}
|
||||
@@ -972,7 +954,7 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
/* Keep track of which device we are */
|
||||
pci_set_drvdata(pdev, wc);
|
||||
|
||||
if (request_irq(pdev->irq, wcfxo_interrupt, IRQF_SHARED, "wcfxo", wc)) {
|
||||
if (request_irq(pdev->irq, wcfxo_interrupt, DAHDI_IRQ_SHARED, "wcfxo", wc)) {
|
||||
printk(KERN_NOTICE "wcfxo: Unable to request IRQ %d\n", pdev->irq);
|
||||
if (wc->freeregion)
|
||||
release_region(wc->ioaddr, 0xff);
|
||||
@@ -994,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 */
|
||||
@@ -1002,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;
|
||||
}
|
||||
@@ -1015,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");
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -160,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 */
|
||||
};
|
||||
|
||||
@@ -274,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");
|
||||
}
|
||||
@@ -773,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);
|
||||
@@ -810,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;
|
||||
}
|
||||
@@ -918,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++) {
|
||||
@@ -1174,8 +1164,6 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
if (!ints)
|
||||
return IRQ_NONE;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
outb(ints, wc->ioaddr + WC_INTSTAT);
|
||||
|
||||
if (!wc->intcount) {
|
||||
@@ -1190,13 +1178,13 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
t1xxp_receiveprep(wc, ints);
|
||||
t1xxp_transmitprep(wc, ints);
|
||||
}
|
||||
spin_lock(&wc->lock);
|
||||
spin_lock_irqsave(&wc->lock, flags);
|
||||
|
||||
#if 1
|
||||
__handle_leds(wc);
|
||||
#endif
|
||||
|
||||
spin_unlock(&wc->lock);
|
||||
spin_unlock_irqrestore(&wc->lock, flags);
|
||||
|
||||
/* Count down timers */
|
||||
t1xxp_do_counters(wc);
|
||||
@@ -1222,8 +1210,6 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
if (ints & 0x20)
|
||||
printk(KERN_INFO "PCI Target abort\n");
|
||||
|
||||
local_irq_restore(flags);
|
||||
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
|
||||
@@ -1337,7 +1323,7 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
/* Keep track of which device we are */
|
||||
pci_set_drvdata(pdev, wc);
|
||||
|
||||
if (request_irq(pdev->irq, t1xxp_interrupt, IRQF_SHARED, "t1xxp", wc)) {
|
||||
if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "t1xxp", wc)) {
|
||||
printk(KERN_NOTICE "t1xxp: Unable to request IRQ %d\n", pdev->irq);
|
||||
kfree(wc);
|
||||
return -EIO;
|
||||
|
||||
@@ -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,10 +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
|
||||
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.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.)
|
||||
endif
|
||||
|
||||
@@ -26,6 +26,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
|
||||
|
||||
8
drivers/dahdi/wct4xxp/Makefile
Normal file
8
drivers/dahdi/wct4xxp/Makefile
Normal 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
@@ -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;
|
||||
@@ -239,7 +227,7 @@ static void vpm450m_setecmode(struct vpm450m *vpm450m, int channel, int mode)
|
||||
|
||||
if (vpm450m->ecmode[channel] == mode)
|
||||
return;
|
||||
modify = kzalloc(sizeof(*modify), GFP_ATOMIC);
|
||||
modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_ATOMIC);
|
||||
if (!modify) {
|
||||
printk(KERN_NOTICE "wct4xxp: Unable to allocate memory for setec!\n");
|
||||
return;
|
||||
@@ -264,12 +252,7 @@ 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 = kzalloc(sizeof(*modify), GFP_KERNEL);
|
||||
modify = kmalloc(sizeof(tOCT6100_CHANNEL_MODIFY), GFP_KERNEL);
|
||||
if (!modify) {
|
||||
printk(KERN_NOTICE "wct4xxp: Unable to allocate memory for setdtmf!\n");
|
||||
return;
|
||||
@@ -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,39 +416,35 @@ 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;
|
||||
|
||||
vpm450m = kzalloc(sizeof(*vpm450m), GFP_KERNEL);
|
||||
if (!vpm450m)
|
||||
if (!(vpm450m = kmalloc(sizeof(struct vpm450m), GFP_KERNEL)))
|
||||
return NULL;
|
||||
|
||||
vpm450m->context.dev = device;
|
||||
vpm450m->context.ops = &wct4xxp_oct612x_ops;
|
||||
memset(vpm450m, 0, sizeof(struct vpm450m));
|
||||
|
||||
ChipOpen = kzalloc(sizeof(*ChipOpen), GFP_KERNEL);
|
||||
if (!ChipOpen) {
|
||||
kfree(vpm450m);
|
||||
if (!(ChipOpen = kmalloc(sizeof(tOCT6100_CHIP_OPEN), GFP_KERNEL))) {
|
||||
kfree(vpm450m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ChannelOpen = kzalloc(sizeof(*ChannelOpen), GFP_KERNEL);
|
||||
if (!ChannelOpen) {
|
||||
memset(ChipOpen, 0, sizeof(tOCT6100_CHIP_OPEN));
|
||||
|
||||
if (!(ChannelOpen = kmalloc(sizeof(tOCT6100_CHANNEL_OPEN), GFP_KERNEL))) {
|
||||
kfree(vpm450m);
|
||||
kfree(ChipOpen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(ChannelOpen, 0, sizeof(tOCT6100_CHANNEL_OPEN));
|
||||
|
||||
for (x = 0; x < ARRAY_SIZE(vpm450m->ecmode); x++)
|
||||
vpm450m->ecmode[x] = -1;
|
||||
|
||||
@@ -487,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;
|
||||
@@ -497,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
|
||||
@@ -544,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)) {
|
||||
@@ -556,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;
|
||||
@@ -573,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;
|
||||
@@ -589,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++) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,12 +113,12 @@ 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
|
||||
#define T4_CHECK_TIMING 3
|
||||
#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)
|
||||
|
||||
|
||||
7
drivers/dahdi/wctc4xxp/Makefile
Normal file
7
drivers/dahdi/wctc4xxp/Makefile
Normal 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,6 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/io.h>
|
||||
#include "proslic.h"
|
||||
|
||||
@@ -206,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;
|
||||
@@ -2144,7 +2142,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
|
||||
|
||||
}
|
||||
|
||||
static int _wctdm_open(struct dahdi_chan *chan)
|
||||
static int wctdm_open(struct dahdi_chan *chan)
|
||||
{
|
||||
struct wctdm *wc = chan->pvt;
|
||||
if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
|
||||
@@ -2155,16 +2153,6 @@ static int _wctdm_open(struct dahdi_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wctdm_open(struct dahdi_chan *chan)
|
||||
{
|
||||
unsigned long flags;
|
||||
int res;
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
res = _wctdm_open(chan);
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline struct wctdm *wctdm_from_span(struct dahdi_span *span)
|
||||
{
|
||||
return container_of(span, struct wctdm, span);
|
||||
@@ -2374,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;
|
||||
@@ -2409,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;
|
||||
@@ -2684,8 +2656,7 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
/* Keep track of which device we are */
|
||||
pci_set_drvdata(pdev, wc);
|
||||
|
||||
if (request_irq(pdev->irq, wctdm_interrupt,
|
||||
IRQF_SHARED, "wctdm", wc)) {
|
||||
if (request_irq(pdev->irq, wctdm_interrupt, DAHDI_IRQ_SHARED, "wctdm", wc)) {
|
||||
printk(KERN_NOTICE "wctdm: Unable to request IRQ %d\n", pdev->irq);
|
||||
if (wc->freeregion)
|
||||
release_region(wc->ioaddr, 0xff);
|
||||
@@ -2706,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;
|
||||
|
||||
@@ -2739,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");
|
||||
}
|
||||
|
||||
|
||||
6
drivers/dahdi/wctdm24xxp/Makefile
Normal file
6
drivers/dahdi/wctdm24xxp/Makefile
Normal 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
@@ -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;
|
||||
|
||||
@@ -299,7 +277,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)
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <linux/ppp_defs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define FAST_HDLC_NEED_TABLES
|
||||
#include <dahdi/kernel.h>
|
||||
@@ -2151,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;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
|
||||
@@ -175,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 */
|
||||
};
|
||||
@@ -225,7 +223,7 @@ static inline void __select_control(struct t1 *wc)
|
||||
}
|
||||
}
|
||||
|
||||
static int _t1xxp_open(struct dahdi_chan *chan)
|
||||
static int t1xxp_open(struct dahdi_chan *chan)
|
||||
{
|
||||
struct t1 *wc = chan->pvt;
|
||||
if (wc->dead)
|
||||
@@ -235,16 +233,6 @@ static int _t1xxp_open(struct dahdi_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int t1xxp_open(struct dahdi_chan *chan)
|
||||
{
|
||||
unsigned long flags;
|
||||
int res;
|
||||
spin_lock_irqsave(&chan->lock, flags);
|
||||
res = _t1xxp_open(chan);
|
||||
spin_unlock_irqrestore(&chan->lock, flags);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int __control_set_reg(struct t1 *wc, int reg, unsigned char val)
|
||||
{
|
||||
__select_control(wc);
|
||||
@@ -352,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");
|
||||
}
|
||||
@@ -990,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;
|
||||
@@ -1031,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;
|
||||
}
|
||||
@@ -1139,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++) {
|
||||
@@ -1351,8 +1330,6 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
if (!ints)
|
||||
return IRQ_NONE;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
outb(ints, wc->ioaddr + WC_INTSTAT);
|
||||
|
||||
if (!wc->intcount) {
|
||||
@@ -1367,13 +1344,13 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
t1xxp_receiveprep(wc, ints);
|
||||
t1xxp_transmitprep(wc, ints);
|
||||
}
|
||||
spin_lock(&wc->lock);
|
||||
spin_lock_irqsave(&wc->lock, flags);
|
||||
|
||||
#if 1
|
||||
__handle_leds(wc);
|
||||
#endif
|
||||
|
||||
spin_unlock(&wc->lock);
|
||||
spin_unlock_irqrestore(&wc->lock, flags);
|
||||
|
||||
/* Count down timers */
|
||||
t1_do_counters(wc);
|
||||
@@ -1400,7 +1377,6 @@ DAHDI_IRQ_HANDLER(t1xxp_interrupt)
|
||||
if (ints & 0x20)
|
||||
printk(KERN_NOTICE "PCI Target abort\n");
|
||||
|
||||
local_irq_restore(flags);
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
|
||||
@@ -1537,8 +1513,7 @@ static int __devinit t1xxp_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
/* Keep track of which device we are */
|
||||
pci_set_drvdata(pdev, wc);
|
||||
|
||||
if (request_irq(pdev->irq, t1xxp_interrupt,
|
||||
IRQF_SHARED, "wcte11xp", wc)) {
|
||||
if (request_irq(pdev->irq, t1xxp_interrupt, DAHDI_IRQ_SHARED_DISABLED, "wcte11xp", wc)) {
|
||||
printk(KERN_NOTICE "wcte11xp: Unable to request IRQ %d\n", pdev->irq);
|
||||
kfree(wc);
|
||||
return -EIO;
|
||||
|
||||
6
drivers/dahdi/wcte12xp/Makefile
Normal file
6
drivers/dahdi/wcte12xp/Makefile
Normal 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
@@ -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
1057
drivers/dahdi/wcxb.c
1057
drivers/dahdi/wcxb.c
File diff suppressed because it is too large
Load Diff
@@ -1,204 +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 12U
|
||||
#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 - Interface to wcxb firmware.
|
||||
* @last_retry_count: Running count of times firmware had to retry host DMA
|
||||
* transaction. Debugging aide.
|
||||
*/
|
||||
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
|
||||
u32 dma_ins:1;
|
||||
} 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;
|
||||
#ifdef DEBUG
|
||||
u8 last_retry_count;
|
||||
u8 max_retry_count;
|
||||
u32 last_dma_time;
|
||||
u32 max_dma_time;
|
||||
#endif
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
enum wcxb_reset_option {
|
||||
WCXB_RESET_NOW,
|
||||
WCXB_RESET_LATER
|
||||
};
|
||||
|
||||
extern u32 wcxb_get_firmware_version(struct wcxb *xb);
|
||||
extern int wcxb_check_firmware(struct wcxb *xb, const u32 expected_version,
|
||||
const char *firmware_filename,
|
||||
bool force_firmware,
|
||||
enum wcxb_reset_option reset);
|
||||
|
||||
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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,387 +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/slab.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;
|
||||
}
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kmod.h>
|
||||
#include "xdefs.h"
|
||||
#include "xpd.h"
|
||||
#include "xpp_dahdi.h"
|
||||
@@ -33,22 +32,21 @@
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
DEF_PARM(charp, initdir, "/usr/share/dahdi", 0644,
|
||||
"The directory of card initialization scripts");
|
||||
DEF_PARM(charp,initdir, "/usr/share/dahdi", 0644, "The directory of card initialization scripts");
|
||||
|
||||
#define CHIP_REGISTERS "chipregs"
|
||||
|
||||
extern int debug;
|
||||
extern int debug;
|
||||
|
||||
/*---------------- GLOBAL PROC handling -----------------------------------*/
|
||||
|
||||
static int send_magic_request(xbus_t *xbus, unsigned unit, xportno_t portno,
|
||||
bool eoftx)
|
||||
static int send_magic_request(xbus_t *xbus,
|
||||
unsigned unit, xportno_t portno, bool eoftx)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Zero length multibyte is legal and has special meaning for the
|
||||
@@ -67,210 +65,203 @@ static int send_magic_request(xbus_t *xbus, unsigned unit, xportno_t portno,
|
||||
dump_xframe(__func__, xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
if (ret < 0)
|
||||
PORT_ERR(xbus, unit, portno, "%s: failed sending xframe\n",
|
||||
__func__);
|
||||
PORT_ERR(xbus, unit, portno,
|
||||
"%s: failed sending xframe\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_hexbyte(const char *buf)
|
||||
{
|
||||
char *endp;
|
||||
unsigned val;
|
||||
char *endp;
|
||||
unsigned val;
|
||||
|
||||
val = simple_strtoul(buf, &endp, 16);
|
||||
if (*endp != '\0' || val > 0xFF)
|
||||
if(*endp != '\0' || val > 0xFF)
|
||||
return -EBADR;
|
||||
return (__u8)val;
|
||||
return (byte)val;
|
||||
}
|
||||
|
||||
static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
|
||||
{
|
||||
int argno;
|
||||
char num_args;
|
||||
int portno;
|
||||
bool writing;
|
||||
int op; /* [W]rite, [R]ead */
|
||||
int addr_mode; /* [D]irect, [I]ndirect, [Mm]ulti */
|
||||
bool do_subreg = 0;
|
||||
int regnum;
|
||||
int subreg;
|
||||
int data_low;
|
||||
bool do_datah;
|
||||
int data_high;
|
||||
int ret = -EBADR;
|
||||
int argno;
|
||||
char num_args;
|
||||
int portno;
|
||||
bool writing;
|
||||
int op; /* [W]rite, [R]ead */
|
||||
int addr_mode; /* [D]irect, [I]ndirect, [Mm]ulti */
|
||||
bool do_subreg = 0;
|
||||
int regnum;
|
||||
int subreg;
|
||||
int data_low;
|
||||
bool do_datah;
|
||||
int data_high;
|
||||
int ret = -EBADR;
|
||||
|
||||
num_args = 2; /* port + operation */
|
||||
if (argc < num_args) {
|
||||
num_args = 2; /* port + operation */
|
||||
if(argc < num_args) {
|
||||
XPD_ERR(xpd, "Not enough arguments (%d)\n", argc);
|
||||
XPD_ERR(xpd,
|
||||
"Any Command is composed of at least %d words "
|
||||
"(got only %d)\n",
|
||||
num_args, argc);
|
||||
"Any Command is composed of at least %d words (got only %d)\n",
|
||||
num_args, argc);
|
||||
goto out;
|
||||
}
|
||||
/* Process the arguments */
|
||||
argno = 0;
|
||||
if (strcmp(argv[argno], "*") == 0) {
|
||||
if(strcmp(argv[argno], "*") == 0) {
|
||||
portno = PORT_BROADCAST;
|
||||
//XPD_DBG(REGS, xpd, "Port broadcast\n");
|
||||
} else {
|
||||
portno = parse_hexbyte(argv[argno]);
|
||||
if (portno < 0 || portno >= 8) {
|
||||
if(portno < 0 || portno >= 8) {
|
||||
XPD_ERR(xpd, "Illegal port number '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
//XPD_DBG(REGS, xpd, "Port is %d\n", portno);
|
||||
}
|
||||
argno++;
|
||||
if (strlen(argv[argno]) != 2) {
|
||||
if(strlen(argv[argno]) != 2) {
|
||||
XPD_ERR(xpd, "Wrong operation codes '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
op = argv[argno][0];
|
||||
switch (op) {
|
||||
case 'W':
|
||||
writing = 1;
|
||||
num_args++; /* data low */
|
||||
//XPD_DBG(REGS, xpd, "WRITING\n");
|
||||
break;
|
||||
case 'R':
|
||||
writing = 0;
|
||||
//XPD_DBG(REGS, xpd, "READING\n");
|
||||
break;
|
||||
default:
|
||||
XPD_ERR(xpd, "Unknown operation type '%c'\n", op);
|
||||
goto out;
|
||||
switch(op) {
|
||||
case 'W':
|
||||
writing = 1;
|
||||
num_args++; /* data low */
|
||||
//XPD_DBG(REGS, xpd, "WRITING\n");
|
||||
break;
|
||||
case 'R':
|
||||
writing = 0;
|
||||
//XPD_DBG(REGS, xpd, "READING\n");
|
||||
break;
|
||||
default:
|
||||
XPD_ERR(xpd, "Unknown operation type '%c'\n", op);
|
||||
goto out;
|
||||
}
|
||||
addr_mode = argv[argno][1];
|
||||
switch (addr_mode) {
|
||||
case 'I':
|
||||
XPD_NOTICE(xpd,
|
||||
"'I' is deprecated in register commands. "
|
||||
"Use 'S' instead.\n");
|
||||
/* fall through */
|
||||
case 'S':
|
||||
do_subreg = 1;
|
||||
num_args += 2; /* register + subreg */
|
||||
//XPD_DBG(REGS, xpd, "SUBREG\n");
|
||||
break;
|
||||
case 'D':
|
||||
do_subreg = 0;
|
||||
num_args++; /* register */
|
||||
//XPD_DBG(REGS, xpd, "DIRECT\n");
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
if (op != 'W') {
|
||||
XPD_ERR(xpd,
|
||||
"Can use Multibyte (%c) only with op 'W'\n",
|
||||
addr_mode);
|
||||
switch(addr_mode) {
|
||||
case 'I':
|
||||
XPD_NOTICE(xpd, "'I' is deprecated in register commands. Use 'S' instead.\n");
|
||||
/* fall through */
|
||||
case 'S':
|
||||
do_subreg = 1;
|
||||
num_args += 2; /* register + subreg */
|
||||
//XPD_DBG(REGS, xpd, "SUBREG\n");
|
||||
break;
|
||||
case 'D':
|
||||
do_subreg = 0;
|
||||
num_args++; /* register */
|
||||
//XPD_DBG(REGS, xpd, "DIRECT\n");
|
||||
break;
|
||||
case 'M':
|
||||
case 'm':
|
||||
if(op != 'W') {
|
||||
XPD_ERR(xpd,
|
||||
"Can use Multibyte (%c) only with op 'W'\n", addr_mode);
|
||||
goto out;
|
||||
}
|
||||
num_args--; /* No data low */
|
||||
//XPD_DBG(REGS, xpd, "Multibyte (%c)\n", addr_mode);
|
||||
break;
|
||||
default:
|
||||
XPD_ERR(xpd, "Unknown addressing type '%c'\n", addr_mode);
|
||||
goto out;
|
||||
}
|
||||
num_args--; /* No data low */
|
||||
//XPD_DBG(REGS, xpd, "Multibyte (%c)\n", addr_mode);
|
||||
break;
|
||||
default:
|
||||
XPD_ERR(xpd, "Unknown addressing type '%c'\n", addr_mode);
|
||||
goto out;
|
||||
}
|
||||
if (argv[argno][2] != '\0') {
|
||||
if(argv[argno][2] != '\0') {
|
||||
XPD_ERR(xpd, "Bad operation field '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
if (argc < num_args) {
|
||||
if(argc < num_args) {
|
||||
XPD_ERR(xpd,
|
||||
"Command \"%s\" is composed of at least %d words "
|
||||
"(got only %d)\n",
|
||||
argv[argno], num_args, argc);
|
||||
"Command \"%s\" is composed of at least %d words (got only %d)\n",
|
||||
argv[argno], num_args, argc);
|
||||
goto out;
|
||||
}
|
||||
argno++;
|
||||
if (addr_mode == 'M' || addr_mode == 'm') {
|
||||
if (argno < argc) {
|
||||
if(addr_mode == 'M' || addr_mode == 'm') {
|
||||
if(argno < argc) {
|
||||
XPD_ERR(xpd,
|
||||
"Magic-Multibyte(%c) with %d extra arguments\n",
|
||||
addr_mode, argc - argno);
|
||||
"Magic-Multibyte(%c) with %d extra arguments\n",
|
||||
addr_mode, argc - argno);
|
||||
goto out;
|
||||
}
|
||||
ret =
|
||||
send_magic_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm');
|
||||
ret = send_magic_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm');
|
||||
goto out;
|
||||
}
|
||||
/* Normal (non-Magic) register commands */
|
||||
do_datah = 0;
|
||||
if (argno >= argc) {
|
||||
if(argno >= argc) {
|
||||
XPD_ERR(xpd, "Missing register number\n");
|
||||
goto out;
|
||||
}
|
||||
regnum = parse_hexbyte(argv[argno]);
|
||||
if (regnum < 0) {
|
||||
if(regnum < 0) {
|
||||
XPD_ERR(xpd, "Illegal register number '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
//XPD_DBG(REGS, xpd, "Register is %X\n", regnum);
|
||||
argno++;
|
||||
if (do_subreg) {
|
||||
if (argno >= argc) {
|
||||
if(do_subreg) {
|
||||
if(argno >= argc) {
|
||||
XPD_ERR(xpd, "Missing subregister number\n");
|
||||
goto out;
|
||||
}
|
||||
subreg = parse_hexbyte(argv[argno]);
|
||||
if (subreg < 0) {
|
||||
XPD_ERR(xpd, "Illegal subregister number '%s'\n",
|
||||
argv[argno]);
|
||||
if(subreg < 0) {
|
||||
XPD_ERR(xpd, "Illegal subregister number '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
//XPD_DBG(REGS, xpd, "Subreg is %X\n", subreg);
|
||||
argno++;
|
||||
} else
|
||||
subreg = 0;
|
||||
if (writing) {
|
||||
if (argno >= argc) {
|
||||
if(writing) {
|
||||
if(argno >= argc) {
|
||||
XPD_ERR(xpd, "Missing data low number\n");
|
||||
goto out;
|
||||
}
|
||||
data_low = parse_hexbyte(argv[argno]);
|
||||
if (data_low < 0) {
|
||||
XPD_ERR(xpd, "Illegal data_low number '%s'\n",
|
||||
argv[argno]);
|
||||
if(data_low < 0) {
|
||||
XPD_ERR(xpd, "Illegal data_low number '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
//XPD_DBG(REGS, xpd, "Data Low is %X\n", data_low);
|
||||
argno++;
|
||||
} else
|
||||
data_low = 0;
|
||||
if (argno < argc) {
|
||||
if(argno < argc) {
|
||||
do_datah = 1;
|
||||
if (!argv[argno]) {
|
||||
if(!argv[argno]) {
|
||||
XPD_ERR(xpd, "Missing data high number\n");
|
||||
goto out;
|
||||
}
|
||||
data_high = parse_hexbyte(argv[argno]);
|
||||
if (data_high < 0) {
|
||||
XPD_ERR(xpd, "Illegal data_high number '%s'\n",
|
||||
argv[argno]);
|
||||
if(data_high < 0) {
|
||||
XPD_ERR(xpd, "Illegal data_high number '%s'\n", argv[argno]);
|
||||
goto out;
|
||||
}
|
||||
//XPD_DBG(REGS, xpd, "Data High is %X\n", data_high);
|
||||
argno++;
|
||||
} else
|
||||
data_high = 0;
|
||||
if (argno < argc) {
|
||||
XPD_ERR(xpd, "Command contains an extra %d argument\n",
|
||||
argc - argno);
|
||||
if(argno < argc) {
|
||||
XPD_ERR(xpd,
|
||||
"Command contains an extra %d argument\n",
|
||||
argc - argno);
|
||||
goto out;
|
||||
}
|
||||
#if 0
|
||||
XPD_DBG(REGS, xpd,
|
||||
"portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d "
|
||||
"dataL=%d do_datah=%d dataH=%d\n",
|
||||
portno, /* portno */
|
||||
writing, /* writing */
|
||||
regnum, do_subreg, /* use subreg */
|
||||
subreg, /* subreg */
|
||||
data_low, do_datah, /* use data_high */
|
||||
data_high);
|
||||
"portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d dataL=%d do_datah=%d dataH=%d\n",
|
||||
portno, /* portno */
|
||||
writing, /* writing */
|
||||
regnum,
|
||||
do_subreg, /* use subreg */
|
||||
subreg, /* subreg */
|
||||
data_low,
|
||||
do_datah, /* use data_high*/
|
||||
data_high);
|
||||
#endif
|
||||
ret = xpp_register_request(xpd->xbus, xpd, portno,
|
||||
writing, regnum, do_subreg, subreg,
|
||||
@@ -279,38 +270,36 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define MAX_ARGS 10
|
||||
|
||||
int parse_chip_command(xpd_t *xpd, char *cmdline)
|
||||
{
|
||||
xbus_t *xbus;
|
||||
int ret = -EBADR;
|
||||
__u8 buf[MAX_PROC_WRITE];
|
||||
char *str;
|
||||
char *p;
|
||||
char *argv[MAX_ARGS + 1];
|
||||
int argc;
|
||||
int i;
|
||||
xbus_t *xbus;
|
||||
int ret = -EBADR;
|
||||
byte buf[MAX_PROC_WRITE];
|
||||
char *str;
|
||||
char *p;
|
||||
static const int MAX_ARGS = 10;
|
||||
char *argv[MAX_ARGS + 1];
|
||||
int argc;
|
||||
int i;
|
||||
|
||||
BUG_ON(!xpd);
|
||||
xbus = xpd->xbus;
|
||||
if (!XBUS_FLAGS(xbus, CONNECTED)) {
|
||||
if(!XBUS_FLAGS(xbus, CONNECTED)) {
|
||||
XBUS_DBG(GENERAL, xbus, "Dropped packet. Disconnected.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
strlcpy(buf, cmdline, MAX_PROC_WRITE); /* Save a copy */
|
||||
if (buf[0] == '#' || buf[0] == ';')
|
||||
if(buf[0] == '#' || buf[0] == ';')
|
||||
XPD_DBG(REGS, xpd, "Note: '%s'\n", buf);
|
||||
if ((p = strchr(buf, '#')) != NULL) /* Truncate comments */
|
||||
if((p = strchr(buf, '#')) != NULL) /* Truncate comments */
|
||||
*p = '\0';
|
||||
if ((p = strchr(buf, ';')) != NULL) /* Truncate comments */
|
||||
if((p = strchr(buf, ';')) != NULL) /* Truncate comments */
|
||||
*p = '\0';
|
||||
/* Trim leading whitespace */
|
||||
for (p = buf; *p && (*p == ' ' || *p == '\t'); p++)
|
||||
for(p = buf; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */
|
||||
;
|
||||
str = p;
|
||||
for (i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS;) {
|
||||
if (*p != '\0') {
|
||||
for(i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS; ) {
|
||||
if(*p != '\0') {
|
||||
argv[i] = p;
|
||||
// XPD_DBG(REGS, xpd, "ARG %d = '%s'\n", i, p);
|
||||
i++;
|
||||
@@ -318,12 +307,11 @@ int parse_chip_command(xpd_t *xpd, char *cmdline)
|
||||
}
|
||||
argv[i] = NULL;
|
||||
argc = i;
|
||||
if (p) {
|
||||
XPD_ERR(xpd, "Too many words (%d) to process. Last was '%s'\n",
|
||||
i, p);
|
||||
if(p) {
|
||||
XPD_ERR(xpd, "Too many words (%d) to process. Last was '%s'\n", i, p);
|
||||
goto out;
|
||||
}
|
||||
if (argc)
|
||||
if(argc)
|
||||
ret = execute_chip_command(xpd, argc, argv);
|
||||
else
|
||||
ret = 0; /* empty command - no op */
|
||||
@@ -340,11 +328,11 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
|
||||
|
||||
/* 0x07 */ HOSTCMD(GLOBAL, AB_REQUEST)
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
int ret = -ENODEV;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
|
||||
if (!xbus) {
|
||||
if(!xbus) {
|
||||
DBG(DEVICES, "NO XBUS\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -354,35 +342,33 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
|
||||
RPACKET_FIELD(pack, GLOBAL, AB_REQUEST, rev) = XPP_PROTOCOL_VERSION;
|
||||
RPACKET_FIELD(pack, GLOBAL, AB_REQUEST, reserved) = 0;
|
||||
XBUS_DBG(DEVICES, xbus, "Protocol Version %d\n", XPP_PROTOCOL_VERSION);
|
||||
if (xbus_setstate(xbus, XBUS_STATE_SENT_REQUEST))
|
||||
if(xbus_setstate(xbus, XBUS_STATE_SENT_REQUEST))
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 ret = 0;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret = 0;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
|
||||
if (!xbus) {
|
||||
if(!xbus) {
|
||||
DBG(REGS, "NO XBUS\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST,
|
||||
xpd->xbus_idx);
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
|
||||
LINE_DBG(REGS, xpd, portno, "%c%c %02X %02X %02X %02X\n",
|
||||
(writing) ? 'W' : 'R', (do_subreg) ? 'S' : 'D', regnum, subreg,
|
||||
data_low, data_high);
|
||||
(writing)?'W':'R',
|
||||
(do_subreg)?'S':'D',
|
||||
regnum, subreg, data_low, data_high);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
/* do not count the 'bytes' field */
|
||||
reg_cmd->bytes = sizeof(*reg_cmd) - 1;
|
||||
reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
|
||||
reg_cmd->is_multibyte = 0;
|
||||
if (portno == PORT_BROADCAST) {
|
||||
if(portno == PORT_BROADCAST) {
|
||||
reg_cmd->portnum = 0;
|
||||
REG_FIELD(reg_cmd, all_ports_broadcast) = 1;
|
||||
} else {
|
||||
@@ -398,15 +384,14 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
||||
REG_FIELD(reg_cmd, do_datah) = do_datah;
|
||||
REG_FIELD(reg_cmd, data_low) = data_low;
|
||||
REG_FIELD(reg_cmd, data_high) = data_high;
|
||||
if (should_reply)
|
||||
if(should_reply)
|
||||
xpd->requested_reply = *reg_cmd;
|
||||
if (debug & DBG_REGS) {
|
||||
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit,
|
||||
reg_cmd->portnum, reg_cmd);
|
||||
if(debug & DBG_REGS) {
|
||||
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit, reg_cmd->portnum, reg_cmd);
|
||||
dump_packet("REG_REQ", pack, 1);
|
||||
}
|
||||
if (!xframe->usec_towait) { /* default processing time of SPI */
|
||||
if (subreg)
|
||||
if(!xframe->usec_towait) { /* default processing time of SPI */
|
||||
if(subreg)
|
||||
xframe->usec_towait = 2000;
|
||||
else
|
||||
xframe->usec_towait = 1000;
|
||||
@@ -414,19 +399,18 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(xpp_register_request);
|
||||
|
||||
/*
|
||||
* The XPD parameter is totaly ignored by the driver and firmware as well.
|
||||
*/
|
||||
/* 0x19 */ HOSTCMD(GLOBAL, SYNC_SOURCE, enum sync_mode mode, int drift)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
const char *mode_name;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
const char *mode_name;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
if ((mode_name = sync_mode_name(mode)) == NULL) {
|
||||
if((mode_name = sync_mode_name(mode)) == NULL) {
|
||||
XBUS_ERR(xbus, "SYNC_SOURCE: bad sync_mode=0x%X\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -443,8 +427,8 @@ EXPORT_SYMBOL(xpp_register_request);
|
||||
*/
|
||||
static int send_xbus_reset(xbus_t *xbus, uint8_t reset_mask)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, XBUS_RESET, 0);
|
||||
@@ -477,14 +461,14 @@ HANDLER_DEF(GLOBAL, NULL_REPLY)
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
|
||||
{ /* 0x08 */
|
||||
struct xbus_workqueue *worker;
|
||||
__u8 rev;
|
||||
struct unit_descriptor *units;
|
||||
int count_units;
|
||||
int i;
|
||||
int ret = 0;
|
||||
HANDLER_DEF(GLOBAL, AB_DESCRIPTION) /* 0x08 */
|
||||
{
|
||||
struct xbus_workqueue *worker;
|
||||
byte rev;
|
||||
struct unit_descriptor *units;
|
||||
int count_units;
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
if (!xbus) {
|
||||
NOTICE("%s: xbus is gone!!!\n", __func__);
|
||||
@@ -492,36 +476,31 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
|
||||
}
|
||||
rev = RPACKET_FIELD(pack, GLOBAL, AB_DESCRIPTION, rev);
|
||||
units = RPACKET_FIELD(pack, GLOBAL, AB_DESCRIPTION, unit_descriptor);
|
||||
count_units = XPACKET_LEN(pack) - ((__u8 *)units - (__u8 *)pack);
|
||||
count_units = XPACKET_LEN(pack) - ((byte *)units - (byte *)pack);
|
||||
count_units /= sizeof(*units);
|
||||
if (rev != XPP_PROTOCOL_VERSION) {
|
||||
if(rev != XPP_PROTOCOL_VERSION) {
|
||||
XBUS_NOTICE(xbus, "Bad protocol version %d (should be %d)\n",
|
||||
rev, XPP_PROTOCOL_VERSION);
|
||||
rev, XPP_PROTOCOL_VERSION);
|
||||
ret = -EPROTO;
|
||||
goto proto_err;
|
||||
}
|
||||
if (count_units > NUM_UNITS) {
|
||||
if(count_units > NUM_UNITS) {
|
||||
XBUS_NOTICE(xbus, "Too many units %d (should be %d)\n",
|
||||
count_units, NUM_UNITS);
|
||||
count_units, NUM_UNITS);
|
||||
ret = -EPROTO;
|
||||
goto proto_err;
|
||||
}
|
||||
if (count_units <= 0) {
|
||||
XBUS_NOTICE(xbus, "Empty astribank? (%d units)\n", count_units);
|
||||
if(count_units <= 0) {
|
||||
XBUS_NOTICE(xbus, "Empty astribank? (%d units)\n",
|
||||
count_units);
|
||||
ret = -EPROTO;
|
||||
goto proto_err;
|
||||
}
|
||||
if (units[0].addr.unit != 0 || units[0].addr.subunit != 0) {
|
||||
XBUS_NOTICE(xbus, "No first module. Astribank unusable.\n");
|
||||
if(!xbus_setstate(xbus, XBUS_STATE_RECVD_DESC)) {
|
||||
ret = -EPROTO;
|
||||
goto proto_err;
|
||||
}
|
||||
if (!xbus_setstate(xbus, XBUS_STATE_RECVD_DESC)) {
|
||||
ret = -EPROTO;
|
||||
goto proto_err;
|
||||
}
|
||||
XBUS_INFO(xbus, "DESCRIPTOR: %d cards, protocol revision %d\n",
|
||||
count_units, rev);
|
||||
XBUS_INFO(xbus, "DESCRIPTOR: %d cards, protocol revision %d\n", count_units, rev);
|
||||
if (xbus_check_unique(xbus))
|
||||
return -EBUSY;
|
||||
xbus->revision = rev;
|
||||
@@ -531,14 +510,12 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
for (i = 0; i < count_units; i++) {
|
||||
struct unit_descriptor *this_unit = &units[i];
|
||||
struct card_desc_struct *card_desc;
|
||||
unsigned long flags;
|
||||
for(i = 0; i < count_units; i++) {
|
||||
struct unit_descriptor *this_unit = &units[i];
|
||||
struct card_desc_struct *card_desc;
|
||||
unsigned long flags;
|
||||
|
||||
if ((card_desc =
|
||||
KZALLOC(sizeof(struct card_desc_struct),
|
||||
GFP_ATOMIC)) == NULL) {
|
||||
if((card_desc = KZALLOC(sizeof(struct card_desc_struct), GFP_ATOMIC)) == NULL) {
|
||||
XBUS_ERR(xbus, "Card description allocation failed.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
@@ -551,15 +528,16 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
|
||||
card_desc->numchips = this_unit->numchips;
|
||||
card_desc->ports_per_chip = this_unit->ports_per_chip;
|
||||
card_desc->port_dir = this_unit->port_dir;
|
||||
card_desc->ports =
|
||||
card_desc->numchips * card_desc->ports_per_chip;
|
||||
XBUS_INFO(xbus,
|
||||
" CARD %d type=%d.%d ports=%d (%dx%d), "
|
||||
"port-dir=0x%02X\n",
|
||||
card_desc->xpd_addr.unit, card_desc->type,
|
||||
card_desc->subtype, card_desc->ports,
|
||||
card_desc->numchips, card_desc->ports_per_chip,
|
||||
card_desc->port_dir);
|
||||
card_desc->ports = card_desc->numchips * card_desc->ports_per_chip;
|
||||
XBUS_INFO(xbus, " CARD %d type=%d.%d ports=%d (%dx%d), port-dir=0x%02X\n",
|
||||
card_desc->xpd_addr.unit,
|
||||
card_desc->type,
|
||||
card_desc->subtype,
|
||||
card_desc->ports,
|
||||
card_desc->numchips,
|
||||
card_desc->ports_per_chip,
|
||||
card_desc->port_dir
|
||||
);
|
||||
spin_lock_irqsave(&worker->worker_lock, flags);
|
||||
worker->num_units++;
|
||||
XBUS_COUNTER(xbus, UNITS)++;
|
||||
@@ -573,7 +551,6 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
|
||||
}
|
||||
goto out;
|
||||
proto_err:
|
||||
xbus_setstate(xbus, XBUS_STATE_FAIL);
|
||||
dump_packet("AB_DESCRIPTION", pack, DBG_ANY);
|
||||
out:
|
||||
return ret;
|
||||
@@ -581,23 +558,21 @@ out:
|
||||
|
||||
HANDLER_DEF(GLOBAL, REGISTER_REPLY)
|
||||
{
|
||||
reg_cmd_t *reg = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REPLY, regcmd);
|
||||
reg_cmd_t *reg = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REPLY, regcmd);
|
||||
|
||||
if (!xpd) {
|
||||
static int rate_limit;
|
||||
if(!xpd) {
|
||||
static int rate_limit;
|
||||
|
||||
if ((rate_limit++ % 1003) < 5)
|
||||
notify_bad_xpd(__func__, xbus, XPACKET_ADDR(pack), "");
|
||||
if((rate_limit++ % 1003) < 5)
|
||||
notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), "");
|
||||
return -EPROTO;
|
||||
}
|
||||
if (debug & DBG_REGS) {
|
||||
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->portnum,
|
||||
reg);
|
||||
if(debug & DBG_REGS) {
|
||||
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->portnum, reg);
|
||||
dump_packet("REG_REPLY", pack, 1);
|
||||
}
|
||||
if (!XMETHOD(card_register_reply, xpd)) {
|
||||
XPD_ERR(xpd,
|
||||
"REGISTER_REPLY: missing card_register_reply()\n");
|
||||
if (! XMETHOD(card_register_reply, xpd)) {
|
||||
XPD_ERR(xpd, "REGISTER_REPLY: without card_register_reply() method\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return CALL_XMETHOD(card_register_reply, xpd, reg);
|
||||
@@ -605,12 +580,12 @@ HANDLER_DEF(GLOBAL, REGISTER_REPLY)
|
||||
|
||||
HANDLER_DEF(GLOBAL, SYNC_REPLY)
|
||||
{
|
||||
__u8 mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
|
||||
__u8 drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
|
||||
const char *mode_name;
|
||||
byte mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
|
||||
byte drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
|
||||
const char *mode_name;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
if ((mode_name = sync_mode_name(mode)) == NULL) {
|
||||
if((mode_name = sync_mode_name(mode)) == NULL) {
|
||||
XBUS_ERR(xbus, "SYNC_REPLY: bad sync_mode=0x%X\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -624,26 +599,24 @@ HANDLER_DEF(GLOBAL, SYNC_REPLY)
|
||||
|
||||
HANDLER_DEF(GLOBAL, ERROR_CODE)
|
||||
{
|
||||
char tmp_name[TMP_NAME_LEN];
|
||||
static long rate_limit;
|
||||
__u8 category_code;
|
||||
__u8 errorbits;
|
||||
char tmp_name[TMP_NAME_LEN];
|
||||
static long rate_limit;
|
||||
byte category_code;
|
||||
byte errorbits;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
if ((rate_limit++ % 5003) > 200)
|
||||
if((rate_limit++ % 5003) > 200)
|
||||
return 0;
|
||||
category_code = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, category_code);
|
||||
errorbits = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, errorbits);
|
||||
if (!xpd) {
|
||||
if(!xpd) {
|
||||
snprintf(tmp_name, TMP_NAME_LEN, "%s(%1d%1d)", xbus->busname,
|
||||
XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
|
||||
XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
|
||||
} else {
|
||||
snprintf(tmp_name, TMP_NAME_LEN, "%s/%s", xbus->busname,
|
||||
xpd->xpdname);
|
||||
snprintf(tmp_name, TMP_NAME_LEN, "%s/%s", xbus->busname, xpd->xpdname);
|
||||
}
|
||||
NOTICE
|
||||
("%s: FIRMWARE %s: category=%d errorbits=0x%02X (rate_limit=%ld)\n",
|
||||
tmp_name, cmd->name, category_code, errorbits, rate_limit);
|
||||
NOTICE("%s: FIRMWARE %s: category=%d errorbits=0x%02X (rate_limit=%ld)\n",
|
||||
tmp_name, cmd->name, category_code, errorbits, rate_limit);
|
||||
dump_packet("FIRMWARE: ", pack, 1);
|
||||
/*
|
||||
* FIXME: Should implement an error recovery plan
|
||||
@@ -651,14 +624,15 @@ HANDLER_DEF(GLOBAL, ERROR_CODE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
xproto_table_t PROTO_TABLE(GLOBAL) = {
|
||||
.entries = {
|
||||
/* Prototable Card Opcode */
|
||||
XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
|
||||
XENTRY( GLOBAL, GLOBAL, AB_DESCRIPTION ),
|
||||
XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
|
||||
XENTRY( GLOBAL, GLOBAL, AB_DESCRIPTION ),
|
||||
XENTRY( GLOBAL, GLOBAL, SYNC_REPLY ),
|
||||
XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
|
||||
XENTRY( GLOBAL, GLOBAL, REGISTER_REPLY ),
|
||||
XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
|
||||
XENTRY( GLOBAL, GLOBAL, REGISTER_REPLY ),
|
||||
},
|
||||
.name = "GLOBAL",
|
||||
.packet_is_valid = global_packet_is_valid,
|
||||
@@ -667,7 +641,7 @@ xproto_table_t PROTO_TABLE(GLOBAL) = {
|
||||
|
||||
static bool global_packet_is_valid(xpacket_t *pack)
|
||||
{
|
||||
const xproto_entry_t *xe;
|
||||
const xproto_entry_t *xe;
|
||||
|
||||
//DBG(GENERAL, "\n");
|
||||
xe = xproto_global_entry(XPACKET_OP(pack));
|
||||
@@ -681,37 +655,28 @@ static void global_packet_dump(const char *msg, xpacket_t *pack)
|
||||
|
||||
#define MAX_PATH_STR 128
|
||||
|
||||
#ifndef UMH_WAIT_PROC
|
||||
/*
|
||||
* - UMH_WAIT_PROC was introduced as enum in 2.6.23
|
||||
* with a value of 1
|
||||
* - It was changed to a macro (and it's value was modified) in 3.3.0
|
||||
*/
|
||||
#define UMH_WAIT_PROC 1
|
||||
#endif
|
||||
|
||||
int run_initialize_registers(xpd_t *xpd)
|
||||
{
|
||||
int ret;
|
||||
xbus_t *xbus;
|
||||
char busstr[MAX_ENV_STR];
|
||||
char busnumstr[MAX_ENV_STR];
|
||||
char modelstr[MAX_ENV_STR];
|
||||
char unitstr[MAX_ENV_STR];
|
||||
char subunitsstr[MAX_ENV_STR];
|
||||
char typestr[MAX_ENV_STR];
|
||||
char directionstr[MAX_ENV_STR];
|
||||
char revstr[MAX_ENV_STR];
|
||||
char connectorstr[MAX_ENV_STR];
|
||||
char xbuslabel[MAX_ENV_STR];
|
||||
char init_card[MAX_PATH_STR];
|
||||
__u8 direction_mask;
|
||||
int i;
|
||||
char *argv[] = {
|
||||
int ret;
|
||||
xbus_t *xbus;
|
||||
char busstr[MAX_ENV_STR];
|
||||
char busnumstr[MAX_ENV_STR];
|
||||
char modelstr[MAX_ENV_STR];
|
||||
char unitstr[MAX_ENV_STR];
|
||||
char subunitsstr[MAX_ENV_STR];
|
||||
char typestr[MAX_ENV_STR];
|
||||
char directionstr[MAX_ENV_STR];
|
||||
char revstr[MAX_ENV_STR];
|
||||
char connectorstr[MAX_ENV_STR];
|
||||
char xbuslabel[MAX_ENV_STR];
|
||||
char init_card[MAX_PATH_STR];
|
||||
byte direction_mask;
|
||||
int i;
|
||||
char *argv[] = {
|
||||
init_card,
|
||||
NULL
|
||||
};
|
||||
char *envp[] = {
|
||||
char *envp[] = {
|
||||
busstr,
|
||||
busnumstr,
|
||||
modelstr,
|
||||
@@ -727,82 +692,74 @@ int run_initialize_registers(xpd_t *xpd)
|
||||
|
||||
BUG_ON(!xpd);
|
||||
xbus = xpd->xbus;
|
||||
if (!initdir || !initdir[0]) {
|
||||
if(!initdir || !initdir[0]) {
|
||||
XPD_NOTICE(xpd, "Missing initdir parameter\n");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
if (!xpd_setstate(xpd, XPD_STATE_INIT_REGS)) {
|
||||
if(!xpd_setstate(xpd, XPD_STATE_INIT_REGS)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
direction_mask = 0;
|
||||
for (i = 0; i < xpd->subunits; i++) {
|
||||
xpd_t *su = xpd_byaddr(xbus, xpd->addr.unit, i);
|
||||
for(i = 0; i < xpd->subunits; i++) {
|
||||
xpd_t *su = xpd_byaddr(xbus, xpd->addr.unit, i);
|
||||
|
||||
if (!su) {
|
||||
XPD_ERR(xpd, "Have %d subunits, but not subunit #%d\n",
|
||||
if(!su) {
|
||||
XPD_ERR(xpd,
|
||||
"Have %d subunits, but not subunit #%d\n",
|
||||
xpd->subunits, i);
|
||||
continue;
|
||||
}
|
||||
direction_mask |=
|
||||
(PHONEDEV(su).direction == TO_PHONE) ? BIT(i) : 0;
|
||||
direction_mask |= (PHONEDEV(su).direction == TO_PHONE) ? BIT(i) : 0;
|
||||
}
|
||||
snprintf(busstr, MAX_ENV_STR, "XBUS_NAME=%s", xbus->busname);
|
||||
snprintf(busnumstr, MAX_ENV_STR, "XBUS_NUMBER=%d", xbus->num);
|
||||
snprintf(modelstr, MAX_ENV_STR, "XBUS_MODEL_STRING=%s",
|
||||
xbus->transport.model_string);
|
||||
snprintf(modelstr, MAX_ENV_STR, "XBUS_MODEL_STRING=%s", xbus->transport.model_string);
|
||||
snprintf(unitstr, MAX_ENV_STR, "UNIT_NUMBER=%d", xpd->addr.unit);
|
||||
snprintf(typestr, MAX_ENV_STR, "UNIT_TYPE=%d", xpd->type);
|
||||
snprintf(subunitsstr, MAX_ENV_STR, "UNIT_SUBUNITS=%d", xpd->subunits);
|
||||
snprintf(directionstr, MAX_ENV_STR, "UNIT_SUBUNITS_DIR=%d",
|
||||
direction_mask);
|
||||
snprintf(directionstr, MAX_ENV_STR, "UNIT_SUBUNITS_DIR=%d", direction_mask);
|
||||
snprintf(revstr, MAX_ENV_STR, "XBUS_REVISION=%d", xbus->revision);
|
||||
snprintf(connectorstr, MAX_ENV_STR, "XBUS_CONNECTOR=%s",
|
||||
xbus->connector);
|
||||
snprintf(connectorstr, MAX_ENV_STR, "XBUS_CONNECTOR=%s", xbus->connector);
|
||||
snprintf(xbuslabel, MAX_ENV_STR, "XBUS_LABEL=%s", xbus->label);
|
||||
if (snprintf
|
||||
(init_card, MAX_PATH_STR, "%s/init_card_%d_%d", initdir, xpd->type,
|
||||
xbus->revision) > MAX_PATH_STR) {
|
||||
XPD_NOTICE(xpd,
|
||||
"Cannot initialize. pathname is longer "
|
||||
"than %d characters.\n",
|
||||
MAX_PATH_STR);
|
||||
if(snprintf(init_card, MAX_PATH_STR, "%s/init_card_%d_%d",
|
||||
initdir, xpd->type, xbus->revision) > MAX_PATH_STR) {
|
||||
XPD_NOTICE(xpd, "Cannot initialize. pathname is longer than %d characters.\n", MAX_PATH_STR);
|
||||
ret = -E2BIG;
|
||||
goto err;
|
||||
}
|
||||
if (!XBUS_IS(xbus, RECVD_DESC)) {
|
||||
XBUS_ERR(xbus,
|
||||
"Skipped register initialization. In state %s.\n",
|
||||
xbus_statename(XBUS_STATE(xbus)));
|
||||
if(!XBUS_IS(xbus, RECVD_DESC)) {
|
||||
XBUS_ERR(xbus, "Skipped register initialization. In state %s.\n",
|
||||
xbus_statename(XBUS_STATE(xbus)));
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
XPD_DBG(DEVICES, xpd, "running '%s' for type=%d revision=%d\n",
|
||||
init_card, xpd->type, xbus->revision);
|
||||
ret = call_usermodehelper(init_card, argv, envp, UMH_WAIT_PROC);
|
||||
init_card, xpd->type, xbus->revision);
|
||||
ret = call_usermodehelper(init_card, argv, envp, 1);
|
||||
/*
|
||||
* Carefully report results
|
||||
*/
|
||||
if (ret == 0)
|
||||
if(ret == 0)
|
||||
XPD_DBG(DEVICES, xpd, "'%s' finished OK\n", init_card);
|
||||
else if (ret < 0) {
|
||||
XPD_ERR(xpd, "Failed running '%s' (errno %d)\n", init_card,
|
||||
ret);
|
||||
else if(ret < 0) {
|
||||
XPD_ERR(xpd, "Failed running '%s' (errno %d)\n", init_card, ret);
|
||||
} else {
|
||||
__u8 exitval = ((unsigned)ret >> 8) & 0xFF;
|
||||
__u8 sigval = ret & 0xFF;
|
||||
byte exitval = ((unsigned)ret >> 8) & 0xFF;
|
||||
byte sigval = ret & 0xFF;
|
||||
|
||||
if (!exitval) {
|
||||
XPD_ERR(xpd, "'%s' killed by signal %d\n", init_card,
|
||||
sigval);
|
||||
if(!exitval) {
|
||||
XPD_ERR(xpd, "'%s' killed by signal %d\n", init_card, sigval);
|
||||
} else {
|
||||
XPD_ERR(xpd, "'%s' aborted with exitval %d\n",
|
||||
init_card, exitval);
|
||||
XPD_ERR(xpd, "'%s' aborted with exitval %d\n", init_card, exitval);
|
||||
}
|
||||
ret = -EINVAL;
|
||||
}
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(sync_mode_name);
|
||||
EXPORT_SYMBOL(run_initialize_registers);
|
||||
EXPORT_SYMBOL(xpp_register_request);
|
||||
|
||||
@@ -26,45 +26,75 @@
|
||||
#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, XBUS_RESET) = 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, XBUS_RESET,
|
||||
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);
|
||||
@@ -72,14 +102,13 @@ DEF_RPACKET_DATA(GLOBAL, ERROR_CODE, __u8 category_code; __u8 errorbits;
|
||||
/* 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
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -3,7 +3,7 @@
|
||||
|
||||
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_1161.201.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)
|
||||
@@ -20,12 +20,4 @@ install:
|
||||
mkdir -p $(TARGET)
|
||||
install $(SCRIPTS) $(TARGET)/
|
||||
install -m 644 ../XppConfig.pm $(FIRMWARES) $(TARGET)/
|
||||
for id in 202 203; do \
|
||||
if [ ! -r $(TARGET)/USB_FW.$$id.hex ]; then \
|
||||
ln -s USB_FW.201.hex $(TARGET)/USB_FW.$$id.hex;\
|
||||
fi; \
|
||||
done
|
||||
if [ ! -r $(TARGET)/FPGA_1161.203.hex ]; then \
|
||||
ln -s FPGA_1161.201.hex $(TARGET)/FPGA_1161.203.hex;\
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# $Id: PIC_TYPE_2.hex 11078 2013-04-11 16:52:37Z dima $
|
||||
# $Id: PIC_TYPE_2.hex 9732 2011-08-24 19:13:55Z dima $
|
||||
#
|
||||
:03000000A5DA4836
|
||||
:03000000A57A4896
|
||||
:03000100C41C41DB
|
||||
:030002000390392F
|
||||
:0300030067967984
|
||||
@@ -42,375 +42,319 @@
|
||||
: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
|
||||
:0300600090AA70F3
|
||||
:03006100205C021E
|
||||
:03006200D2018048
|
||||
:03006300D40E07B1
|
||||
:0300640003D6437D
|
||||
:03006500C1CA739A
|
||||
:03006600022C0366
|
||||
:0300670020618095
|
||||
:03006800643E07EC
|
||||
:03006900A6E643C5
|
||||
:03006A00322A73C4
|
||||
:03006B002C8C04D6
|
||||
:03006C00D0018040
|
||||
:03006D00A68E0755
|
||||
:03006E00C0164376
|
||||
:03006F00142A73DD
|
||||
:03007000743C01DC
|
||||
:03007100ACB038F8
|
||||
:03007200206A728F
|
||||
:0300730090AC1836
|
||||
:03007400205038E1
|
||||
:03007500D202199B
|
||||
:03007600D40E0F96
|
||||
:0300770003D02291
|
||||
:03007800C04C0079
|
||||
:030079000220382A
|
||||
:03006700C0018055
|
||||
:03006800024E073E
|
||||
:0300690021D6435A
|
||||
:03006A00030A7313
|
||||
:03006B00901C04E2
|
||||
:03006C00202180D0
|
||||
:03006D00030E0778
|
||||
:03006E00901643A6
|
||||
:03006F00204A73B1
|
||||
:03007000030C017D
|
||||
:03007100901038B4
|
||||
:03007200210A72EE
|
||||
:03007300024C1824
|
||||
:03007400C0303861
|
||||
:0300750008421925
|
||||
:03007600603E0FDA
|
||||
:03007700A7A0221D
|
||||
:03007800209C00C9
|
||||
:03007900A7C038E5
|
||||
: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
|
||||
:03007B00A7CE0706
|
||||
:03007C00187F02E8
|
||||
:03007D0014974392
|
||||
:03007E00643A835E
|
||||
:03007F00AABC0018
|
||||
:030080001A7031C2
|
||||
:03008100C50C1299
|
||||
:03008200039A904E
|
||||
:030083007992006F
|
||||
:03008400A83E078C
|
||||
:0300850020BF0396
|
||||
:03008600D007435D
|
||||
:03008700038A8C5D
|
||||
:03008800219C00B8
|
||||
:03008900E07031F3
|
||||
:03008A00348C189B
|
||||
:03008B00348A9024
|
||||
:03008C00348C00B1
|
||||
:03008D003480318B
|
||||
:03008E00030C164A
|
||||
:03008F00206A9054
|
||||
:0300900034803B7E
|
||||
:03009100348E0F9B
|
||||
:0300920034808235
|
||||
:03009300348703AC
|
||||
:03009400D05A9AA5
|
||||
:03009500031C0F3A
|
||||
:03009600C00FFF99
|
||||
:0300970003215BE7
|
||||
:030098000331022F
|
||||
:03009900C70A9BF8
|
||||
:03009A0003921BB3
|
||||
:03009B00C500306D
|
||||
:03009C00039E0FB1
|
||||
:03009D00C1C03BA4
|
||||
:03009E00030C024E
|
||||
:03009F00C0003965
|
||||
:0300A000031C003E
|
||||
:0300A100204039C3
|
||||
:0300A200032C80AC
|
||||
: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
|
||||
:0300A400033039ED
|
||||
:0300A500C70C0085
|
||||
:0300A6000390398B
|
||||
:0300A700C50C4045
|
||||
:0300A80003903989
|
||||
:0300A900C407D9B0
|
||||
:0300AA00039AA90D
|
||||
:0300AB0020CC0066
|
||||
:0300AC0074302687
|
||||
:0300AD00B1702708
|
||||
:0300AE00C0002B64
|
||||
:0300AF00024020EC
|
||||
:0300B000C05C032E
|
||||
:0300B10002202CFE
|
||||
:0300B200205C20AF
|
||||
:0300B300D20D80EB
|
||||
:0300B400D4002550
|
||||
:0300B50003DC2049
|
||||
:0300B60021D02432
|
||||
:0300B700030C0037
|
||||
:0300B80090102283
|
||||
:0300B900202205FD
|
||||
:0300BA0003003010
|
||||
:0300BB0090190198
|
||||
:0300BC00204204DB
|
||||
:0300BD000300300D
|
||||
:0300BE0090190195
|
||||
:0300BF00C012026A
|
||||
:0300C000150030F8
|
||||
:0300C100024901F0
|
||||
:0300C20021DC40FE
|
||||
:0300C300030039FE
|
||||
:0300C400901C018C
|
||||
:0300C500202037C1
|
||||
:0300C600030C60C8
|
||||
:0300C7009012C8CC
|
||||
:0300C800204AC704
|
||||
:0300C900030C0025
|
||||
:0300CA009010375C
|
||||
:0300CB002066D9D3
|
||||
:0300CC0090AAD027
|
||||
:0300CD002056F9C1
|
||||
:0300CE00D20B4D05
|
||||
:0300C20021AC402E
|
||||
:0300C3009420394D
|
||||
:0300C400202C01EC
|
||||
:0300C50003A0375E
|
||||
:0300C600206C604B
|
||||
:0300C7007432C8C8
|
||||
:0300C800AD5AC767
|
||||
:0300C900C9FC006F
|
||||
:0300CA0016B03736
|
||||
:0300CB00C006D993
|
||||
:0300CC006B0AD0EC
|
||||
:0300CD00D206F95F
|
||||
:0300CE006D0B4D6A
|
||||
: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
|
||||
:0300D00012B94022
|
||||
:0300D100C80C2038
|
||||
:0300D2001AB195CB
|
||||
:0300D30020B64311
|
||||
:0300D400038ADFBD
|
||||
:0300D500206C019B
|
||||
:0300D60002A1DFA5
|
||||
:0300D700C0409B8B
|
||||
:0300D800086703B3
|
||||
:0300D900703ADF9B
|
||||
:0300DA00ADE7D3BC
|
||||
:0300DB00C00B480F
|
||||
:0300DC00024CFFD4
|
||||
:0300DD00AE202230
|
||||
:0300DE00C04B2AEA
|
||||
:0300DF000AA21F53
|
||||
:0300E000C0290A2A
|
||||
:0300E100024C20AE
|
||||
:0300E200917125F4
|
||||
:0300E300C016D371
|
||||
:0300E40003EAEA42
|
||||
:0300E500206C206C
|
||||
:0300E600643095EE
|
||||
:0300E700AEB6436F
|
||||
:0300E80037EAF202
|
||||
:0300E9002C8AEF6F
|
||||
:0300EA00AE8C4099
|
||||
:0300EB00C6012526
|
||||
:0300EC00150C00F0
|
||||
:0300ED0074302448
|
||||
:0300EE00AFFB1A4B
|
||||
:0300EF0021E217F4
|
||||
:0300F0001AF024DF
|
||||
:0300F10014FB1AE3
|
||||
:0300F200743C401B
|
||||
:0300F300B17105E3
|
||||
:0300F400C0403DCC
|
||||
:0300F500124C00AA
|
||||
:0300F600917024E2
|
||||
:0300F700C0021D27
|
||||
:0300F80002403093
|
||||
:0300F900200901DA
|
||||
:0300FA0094221538
|
||||
:0300FB0020203092
|
||||
:0300FC00020901F5
|
||||
:0300FD00035204A7
|
||||
:0300FE00B17030AE
|
||||
:0300FF00CFF90135
|
||||
:0301000019E210F1
|
||||
:0301010016F024D1
|
||||
:03010200C037F70C
|
||||
:03010300081B0BCB
|
||||
:03010400743C0246
|
||||
:03010500B0EFFF59
|
||||
:03010600C01164C1
|
||||
:03010700024C02A5
|
||||
:030108002001577C
|
||||
:030109009421241A
|
||||
:03010A00202B1790
|
||||
:03010B000207D711
|
||||
:03010C00035B177B
|
||||
:03010D00B17C01C1
|
||||
:03010E00C00FFF20
|
||||
:03010F0018116460
|
||||
:03011000643C014B
|
||||
:030111006B015728
|
||||
:03011200B14124D4
|
||||
:03011300B17B17A6
|
||||
:03011400C01217FF
|
||||
:0301150012402471
|
||||
:03011600917B17C3
|
||||
:03011700369C0211
|
||||
:03011800C01D0106
|
||||
:030119001E616400
|
||||
:03011A0021BC8085
|
||||
:03011B000866F380
|
||||
:03011C0074312516
|
||||
:03011D00A57205C3
|
||||
:03011E000260304C
|
||||
:03011F00C02901F3
|
||||
:03012000FFF215D6
|
||||
:0301210016B030E5
|
||||
:03012200C02901F0
|
||||
:0301230023A20410
|
||||
:0301240074303004
|
||||
:0301250012B9010B
|
||||
:0301260020B7D32C
|
||||
:03012700038B48FF
|
||||
:03012800C44210BE
|
||||
:030129000390221E
|
||||
:03012A00C40C50B2
|
||||
:03012B0003903905
|
||||
:03012C00C0079970
|
||||
:03012D00023B2C66
|
||||
:03012E00AC2212EE
|
||||
:03012F00B2F030FB
|
||||
:03013000000214B6
|
||||
:030131000000319A
|
||||
:03013200000213B5
|
||||
:0301330000003297
|
||||
:03013400000C00BC
|
||||
:0301350000003394
|
||||
:03013600000C704A
|
||||
:030137000000398C
|
||||
:03013800000C5068
|
||||
:030139000000398A
|
||||
:03013A00000215AB
|
||||
:03013B0000003091
|
||||
:03013C00000C00B4
|
||||
:03013D000000318E
|
||||
:03013E00000202BA
|
||||
:03013F000000328B
|
||||
:03014000000C00B0
|
||||
:0301410000003388
|
||||
:03014200000C703E
|
||||
:0301430000003980
|
||||
:03014400000C505C
|
||||
:030145000000397E
|
||||
:03014600000C406A
|
||||
:030147000000397C
|
||||
:03014800000C00A8
|
||||
:030149000000397A
|
||||
:03014A00000C00A6
|
||||
:03014B00000C00A5
|
||||
:03014C00000AC2E4
|
||||
:03014D00000C00A3
|
||||
:03014E0000002589
|
||||
:03014F00000C1091
|
||||
:0301500000003D6F
|
||||
:030151000009178B
|
||||
:03015200000C049A
|
||||
:0301530000002584
|
||||
:03015400000C009C
|
||||
:0301550000003D6A
|
||||
:0301560000091786
|
||||
:03015700000C0297
|
||||
:030158000000257F
|
||||
:03015900000C088F
|
||||
:03015A0000003D65
|
||||
:03015B0000091781
|
||||
:03015C00000C0094
|
||||
:03015D0000002679
|
||||
:03015E00000C0191
|
||||
:03015F0000002974
|
||||
:03016000000C2070
|
||||
:0301610000002378
|
||||
:03016200000A0090
|
||||
:03016300000B632B
|
||||
:00000001FF
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: USB_FW.201.hex 11453 2015-03-29 18:27:25Z dima $
|
||||
# $Id: USB_FW.201.hex 10402 2012-02-15 15:34:50Z dima $
|
||||
#
|
||||
:03004300021F0099
|
||||
:03005300021F0089
|
||||
@@ -27,7 +27,7 @@
|
||||
:050FF6000300000000F3
|
||||
:100F3C0041E0370041E0B60042E0B1000041E0384A
|
||||
:100F4C0000021BE0850218E07943E0B30000004D7D
|
||||
:0F0F5C00E03931313435314D2020202020200064
|
||||
:0F0F5C00E03931303339354D202020202020005E
|
||||
:101D71008B538A548955E5581558AE57700215573B
|
||||
:101D81004E6014AB530555E555AA54700205541421
|
||||
:081D9100F9ED12077780DF2253
|
||||
@@ -164,7 +164,7 @@
|
||||
:100B7E00AB45AA46A9477401120777E4F550E55034
|
||||
:100B8E00C454F0AB45AA46A94790000112078985C7
|
||||
:100B9E004858854959854A5A755B08121A95AB48CB
|
||||
:100BAE00AA49A94A90000212074AFE5407FFEE54C2
|
||||
:100BAE00AA49A94A90000212074AFE5403FFEE54C6
|
||||
:100BBE0070F55124E0602924F0604B24F0605D2430
|
||||
:100BCE00F0606F24406003020C5675410185184297
|
||||
:100BDE00851943EF24FE600624FE703B801C801FA7
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user