Compare commits
184 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53a8c5626e | ||
|
|
6ced49ebdd | ||
|
|
79e20be476 | ||
|
|
396f1a76b1 | ||
|
|
ca95a19f41 | ||
|
|
41c3c2e879 | ||
|
|
c98b3a689e | ||
|
|
9deb9b2a4f | ||
|
|
0a92282cfe | ||
|
|
3c800538f7 | ||
|
|
6384cb034a | ||
|
|
0ecf2c67c8 | ||
|
|
89ea0430df | ||
|
|
05bac84ce8 | ||
|
|
5b675ab400 | ||
|
|
69774cd457 | ||
|
|
9dde3cff9c | ||
|
|
e15edb0d7a | ||
|
|
848d5ae115 | ||
|
|
fa86c13c3b | ||
|
|
bad3860f24 | ||
|
|
5fcf13fdef | ||
|
|
7c99a670b5 | ||
|
|
91a94133f1 | ||
|
|
4f487f8d7d | ||
|
|
77437503a8 | ||
|
|
8297239209 | ||
|
|
28d13b909c | ||
|
|
52b56c9848 | ||
|
|
eff796fd8f | ||
|
|
00ef2bfa13 | ||
|
|
a2bfd1d4c2 | ||
|
|
6009f56f8b | ||
|
|
7a497cee43 | ||
|
|
853b69a106 | ||
|
|
adfcd9d864 | ||
|
|
2b2054f28b | ||
|
|
6e1058eae0 | ||
|
|
8067ae3269 | ||
|
|
54b9983407 | ||
|
|
b4989839bc | ||
|
|
3876f253a6 | ||
|
|
005aa723ef | ||
|
|
808b2dd408 | ||
|
|
081977bc94 | ||
|
|
f06c8d50cf | ||
|
|
17a2ce9421 | ||
|
|
5ed0271397 | ||
|
|
48b3cb8777 | ||
|
|
d726b04767 | ||
|
|
e5ed586e31 | ||
|
|
6f2a52b764 | ||
|
|
b91ec305be | ||
|
|
afe3702873 | ||
|
|
892e49c356 | ||
|
|
9fd76d93c9 | ||
|
|
6706b03d9d | ||
|
|
2ae396112a | ||
|
|
b6f3466607 | ||
|
|
9ce15dc967 | ||
|
|
2b11667c47 | ||
|
|
6b6d047241 | ||
|
|
2983075256 | ||
|
|
b43c7f02a0 | ||
|
|
990af593a5 | ||
|
|
654486dc24 | ||
|
|
6d1713c2c0 | ||
|
|
da149b0d4d | ||
|
|
06961f8605 | ||
|
|
2a3a074f33 | ||
|
|
c4616c6c86 | ||
|
|
244c9bd254 | ||
|
|
cc7c73c4d8 | ||
|
|
66eb65dda7 | ||
|
|
1372573e68 | ||
|
|
1e22667c31 | ||
|
|
8bcab23272 | ||
|
|
1a79cb4fdc | ||
|
|
bc7c111d7e | ||
|
|
4b58524565 | ||
|
|
6ed54cc7e3 | ||
|
|
09e46f2213 | ||
|
|
875c1ec3b6 | ||
|
|
382125f880 | ||
|
|
1e561e4ed7 | ||
|
|
f0c61c85b8 | ||
|
|
74d86c535d | ||
|
|
0c89cad864 | ||
|
|
e74fb7d04d | ||
|
|
c7228589a9 | ||
|
|
6a1561b749 | ||
|
|
ce261cd03a | ||
|
|
a054cddc09 | ||
|
|
fde1081677 | ||
|
|
e3c07497ee | ||
|
|
11d8140b23 | ||
|
|
47beee98d7 | ||
|
|
f9326ca60f | ||
|
|
d556a1a57a | ||
|
|
3fc23b4465 | ||
|
|
4d10eab759 | ||
|
|
8f4a626087 | ||
|
|
bf3d8aa2cd | ||
|
|
aab9e51f30 | ||
|
|
bfae9c07da | ||
|
|
7c4c826d68 | ||
|
|
d91b3c53d3 | ||
|
|
39c4b93ed6 | ||
|
|
f9c52bb271 | ||
|
|
8d23f878d4 | ||
|
|
a6824019fb | ||
|
|
2794bb4937 | ||
|
|
935c9ba50a | ||
|
|
38c3cda8e2 | ||
|
|
3998c8fd11 | ||
|
|
33c31e9593 | ||
|
|
4b1a2f9127 | ||
|
|
35ffe2f550 | ||
|
|
f06aa486c7 | ||
|
|
e14f3fa541 | ||
|
|
955641b52c | ||
|
|
b7485aa383 | ||
|
|
a81fb56b5f | ||
|
|
ef426966d6 | ||
|
|
133be4bb27 | ||
|
|
73764a1dc9 | ||
|
|
19e874f682 | ||
|
|
22e054a958 | ||
|
|
20ee5f5b0c | ||
|
|
ac09987a59 | ||
|
|
eae6c0d1e7 | ||
|
|
0544f8c7cc | ||
|
|
a01f74d64a | ||
|
|
58514bc801 | ||
|
|
fabe174b83 | ||
|
|
d8c0898fb7 | ||
|
|
fbc506c865 | ||
|
|
2c4dad3c58 | ||
|
|
2c341b481e | ||
|
|
9c8eb34337 | ||
|
|
fba8fd1a70 | ||
|
|
534c7e7547 | ||
|
|
f02b476fee | ||
|
|
4231523c2f | ||
|
|
ae2785e0e7 | ||
|
|
4edd8a1973 | ||
|
|
17e0f2b7bb | ||
|
|
5afc62e856 | ||
|
|
dafb5f401b | ||
|
|
e025a651fb | ||
|
|
dfab257fef | ||
|
|
6fcd923dee | ||
|
|
1ba9a007d1 | ||
|
|
d4ee448c7e | ||
|
|
dc6ef91241 | ||
|
|
0c5b91cc80 | ||
|
|
57f80508b5 | ||
|
|
17f0170829 | ||
|
|
874b76bd22 | ||
|
|
cea4b8bda3 | ||
|
|
60caca49f4 | ||
|
|
b5bacb94a7 | ||
|
|
a2aba65e0c | ||
|
|
32bb7d4c10 | ||
|
|
fd3eb2da05 | ||
|
|
25cb4126c8 | ||
|
|
3d8629e864 | ||
|
|
1d03f6f8a8 | ||
|
|
cfafd3a7b7 | ||
|
|
a3fd58979d | ||
|
|
77ec2dce9f | ||
|
|
cdeaafb910 | ||
|
|
41c24c400e | ||
|
|
f74112b551 | ||
|
|
0bc7ff0816 | ||
|
|
ad4489c7f4 | ||
|
|
1862d8040c | ||
|
|
3b20fe39af | ||
|
|
eda8ceea1c | ||
|
|
e25a65b692 | ||
|
|
4f8b2dded1 | ||
|
|
77113b822f | ||
|
|
c793b1b173 | ||
|
|
d401ad4233 |
187
README
187
README
@@ -17,6 +17,7 @@ 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
|
||||
@@ -211,13 +212,10 @@ under driver/staging/echo . In fact, dahdi_echocan_oslec assumes that
|
||||
this is where the oslec code lies. If it is elsewhere you'll need to fix
|
||||
the #include line.
|
||||
|
||||
Thus for the moment, the simplest way to build OSLEC with dahdi is:
|
||||
|
||||
1. Copy the directory `drivers/staging/echo` from a recent kernel tree
|
||||
(at least 2.6.28-rc1) to the a subdirectory with the same name in the
|
||||
dahdi-linux tree.
|
||||
|
||||
2. Edit drivers/dahdi/Kbuild and uncomment the two lines related to OSLEC.
|
||||
Thus for the moment, the simplest way to build OSLEC with dahdi is to
|
||||
copy the directory `drivers/staging/echo` from a recent kernel tree (at
|
||||
least 2.6.28-rc1) to the a subdirectory with the same name in the
|
||||
dahdi-linux tree.
|
||||
|
||||
After doing that, you'll see the following when building (running
|
||||
'make')
|
||||
@@ -538,6 +536,7 @@ 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.
|
||||
@@ -557,6 +556,81 @@ 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.
|
||||
@@ -644,6 +718,103 @@ see an extra '(In use)':
|
||||
2 XPP_FXS/0/0/1 FXOLS (In use)
|
||||
|
||||
|
||||
SysFS Interface
|
||||
~~~~~~~~~~~~~~~
|
||||
DAHDI exposes several interfaces under the SysFS virtual file system.
|
||||
SysFS represents kernel objects in nodes - directories. There properties
|
||||
are often files. They may also contain other nodes or include symlinks
|
||||
to other nodes.
|
||||
|
||||
Class DAHDI
|
||||
^^^^^^^^^^^
|
||||
under /sys/class/dadhi there exists a node for each DAHDI device file
|
||||
under /dev/dahdi. The name is 'dahdi!foo' for the file '/dev/dahdi/foo'
|
||||
(udev translates exclamation marks to slashes). Those nodes are not, for
|
||||
the most part, proper SysFS nodes, and don't include any interesting
|
||||
properties.
|
||||
|
||||
|
||||
Devices Bus
|
||||
^^^^^^^^^^^
|
||||
Each DAHDI device (a physical device, such as a PCI card) is represented
|
||||
by a node under /sys/bus/dahdi_devices/devices named with the name of
|
||||
its device.
|
||||
|
||||
Its attributes include:
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/assgin-span
|
||||
Write-only attribute: this device's spans should now be assigned
|
||||
("registered"). See section about <<_span_assignments>>.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/auto-assign
|
||||
Write-only attribute. Spans in the device auto-assign ("register" as in
|
||||
the original interface). See section about <<_span_assignments>>.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/hardware_id
|
||||
A unique hardware-level identifier (e.g. serial number), if available.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/manufacturer
|
||||
The name of the manufacturer. Freeform-string.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/spantype
|
||||
A line for each available span: <num>:<type>. This has to be provided
|
||||
here as in the case of manual assignment, userspace may need to know
|
||||
it before span nodes are created.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/spantype
|
||||
Device type.
|
||||
|
||||
===== /sys/bus/dahdi_devices/devices/DEVICE/unassign-span
|
||||
Write-only attribute: the span whose device-local number is written
|
||||
should now be unassigned ("unregistered"). See section about
|
||||
<<_span_assignments>>.
|
||||
|
||||
|
||||
Spans Bus
|
||||
^^^^^^^^^
|
||||
Each DAHDI span is represented by a node under
|
||||
/sys/bus/dahdi_spans/devices with the name 'span-N' (where N is the
|
||||
number of the span). Spans of each device also reside under the node of
|
||||
the device.
|
||||
|
||||
Useful attributes in the span node:
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/alarms
|
||||
The alarms of the span. Currently this is a numeric representation.
|
||||
This may change in the future.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/basechan
|
||||
The channel number of the first channel. The channel numbers of the
|
||||
following channels are guaranteed to follow it.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/channels
|
||||
The number of the channels in the span.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/desc
|
||||
A free-form description of the span.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/is_digital
|
||||
1 if the span is digital, 0 if it isn't.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/is_sync_master
|
||||
1 if the span is the sync master, 0 if it isn't.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/lbo
|
||||
LBO setting for the channel.
|
||||
|
||||
===== /sys/bus/dahdi_spans/devices/span-N/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.
|
||||
|
||||
|
||||
User-space Interface
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
User-space programs can only work with DAHDI channels. The basic
|
||||
@@ -721,7 +892,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_register()'.
|
||||
spans with the DAHDI core using 'dahdi_device_register()'.
|
||||
|
||||
'struct dahdi_span' has a number of informative members that are updated
|
||||
solely by the low-level driver:
|
||||
|
||||
@@ -293,6 +293,10 @@ 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
|
||||
|
||||
@@ -6,6 +6,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETH) += dahdi_dynamic_eth.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF) += dahdi_dynamic_ethmf.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o
|
||||
|
||||
ifdef CONFIG_PCI
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
|
||||
@@ -20,6 +21,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE11XP) += wcte11xp.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCFXO) += wcfxo.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TOR2) += tor2.o
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_PCIRADIO) += pciradio.o
|
||||
endif
|
||||
|
||||
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_XPP) += xpp/
|
||||
|
||||
@@ -31,14 +33,13 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_ECHOCAN_MG2) += dahdi_echocan_mg2.o
|
||||
|
||||
obj-m += $(DAHDI_MODULES_EXTRA)
|
||||
|
||||
# Only enable this if you think you know what you're doing. This is not
|
||||
# supported yet:
|
||||
#obj-m += dahdi_echocan_oslec.o
|
||||
#
|
||||
# A quick and dirty way to build OSLEC, if you happened to place it
|
||||
# yourself in the dahdi source tree. This is experimental. See README
|
||||
# regarding OSLEC.
|
||||
#obj-m += ../staging/echo/
|
||||
# If you want to build OSLEC, include the code in the standard location:
|
||||
# drivers/staging/echo . The DAHDI OSLEC echo canceller will be built as
|
||||
# well:
|
||||
ifneq (,$(wildcard $(src)/../staging/echo/echo.c))
|
||||
obj-m += dahdi_echocan_oslec.o
|
||||
obj-m += ../staging/echo/
|
||||
endif
|
||||
|
||||
CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,6 +49,305 @@ static struct class_simple *dahdi_class = NULL;
|
||||
#define class_destroy class_simple_destroy
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Very old hotplug support
|
||||
*/
|
||||
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 9)
|
||||
#define OLD_HOTPLUG_SUPPORT /* for older kernels */
|
||||
#define OLD_HOTPLUG_SUPPORT_269
|
||||
#endif
|
||||
|
||||
#ifdef OLD_HOTPLUG_SUPPORT_269
|
||||
/* Copy from new kernels lib/kobject_uevent.c */
|
||||
enum kobject_action {
|
||||
KOBJ_ADD,
|
||||
KOBJ_REMOVE,
|
||||
KOBJ_CHANGE,
|
||||
KOBJ_MOUNT,
|
||||
KOBJ_UMOUNT,
|
||||
KOBJ_OFFLINE,
|
||||
KOBJ_ONLINE,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hotplug replaced with uevent in 2.6.16
|
||||
*/
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16)
|
||||
#define OLD_HOTPLUG_SUPPORT /* for older kernels */
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14)
|
||||
#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)
|
||||
#else
|
||||
#define DEVICE_ATTR_READER(name, dev, buf) \
|
||||
ssize_t name(struct device *dev, char *buf)
|
||||
#define DEVICE_ATTR_WRITER(name, dev, buf, count) \
|
||||
ssize_t name(struct device *dev, const char *buf, size_t count)
|
||||
#define BUS_ATTR_READER(name, dev, buf) \
|
||||
ssize_t name(struct device *dev, char *buf)
|
||||
#define BUS_ATTR_WRITER(name, dev, buf, count) \
|
||||
ssize_t name(struct device *dev, const char *buf, size_t count)
|
||||
#endif
|
||||
|
||||
#define DRIVER_ATTR_READER(name, drv, buf) \
|
||||
ssize_t name(struct device_driver *drv, char * buf)
|
||||
|
||||
|
||||
static char *initdir = "/usr/share/dahdi";
|
||||
module_param(initdir, charp, 0644);
|
||||
|
||||
static int span_match(struct device *dev, struct device_driver *driver)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline struct dahdi_span *dev_to_span(struct device *dev)
|
||||
{
|
||||
return dev_get_drvdata(dev);
|
||||
}
|
||||
|
||||
#ifdef OLD_HOTPLUG_SUPPORT
|
||||
static int span_hotplug(struct device *dev, char **envp, int envnum,
|
||||
char *buff, int bufsize)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
span = dev_to_span(dev);
|
||||
envp[0] = buff;
|
||||
if (snprintf(buff, bufsize, "SPAN_NAME=%s", span->name) >= bufsize)
|
||||
return -ENOMEM;
|
||||
envp[1] = NULL;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#define SPAN_VAR_BLOCK \
|
||||
do { \
|
||||
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s", initdir); \
|
||||
DAHDI_ADD_UEVENT_VAR("SPAN_NUM=%d", span->spanno); \
|
||||
DAHDI_ADD_UEVENT_VAR("SPAN_NAME=%s", span->name); \
|
||||
} while (0)
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
|
||||
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
|
||||
do { \
|
||||
int err = add_uevent_var(envp, num_envp, &i, \
|
||||
buffer, buffer_size, &len, \
|
||||
fmt, val); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
static int span_uevent(struct device *dev, char **envp, int num_envp,
|
||||
char *buffer, int buffer_size)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
int i = 0;
|
||||
int len = 0;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
if (!span)
|
||||
return -ENODEV;
|
||||
|
||||
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
|
||||
dev_name(dev), span->name);
|
||||
SPAN_VAR_BLOCK;
|
||||
envp[i] = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
|
||||
do { \
|
||||
int err = add_uevent_var(kenv, fmt, val); \
|
||||
if (err) \
|
||||
return err; \
|
||||
} while (0)
|
||||
|
||||
static int span_uevent(struct device *dev, struct kobj_uevent_env *kenv)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
if (!dev)
|
||||
return -ENODEV;
|
||||
span = dev_to_span(dev);
|
||||
if (!span)
|
||||
return -ENODEV;
|
||||
dahdi_dbg(GENERAL, "SYFS dev_name=%s span=%s\n",
|
||||
dev_name(dev), span->name);
|
||||
SPAN_VAR_BLOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* OLD_HOTPLUG_SUPPORT */
|
||||
|
||||
#define span_attr(field, format_string) \
|
||||
static BUS_ATTR_READER(field##_show, dev, buf) \
|
||||
{ \
|
||||
struct dahdi_span *span; \
|
||||
\
|
||||
span = dev_to_span(dev); \
|
||||
return sprintf(buf, format_string, span->field); \
|
||||
}
|
||||
|
||||
span_attr(name, "%s\n");
|
||||
span_attr(desc, "%s\n");
|
||||
span_attr(spantype, "%s\n");
|
||||
span_attr(alarms, "0x%x\n");
|
||||
span_attr(lbo, "%d\n");
|
||||
span_attr(syncsrc, "%d\n");
|
||||
|
||||
static BUS_ATTR_READER(local_spanno_show, dev, buf)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
return sprintf(buf, "%d\n", local_spanno(span));
|
||||
}
|
||||
|
||||
static BUS_ATTR_READER(is_digital_show, dev, buf)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
return sprintf(buf, "%d\n", dahdi_is_digital_span(span));
|
||||
}
|
||||
|
||||
static BUS_ATTR_READER(is_sync_master_show, dev, buf)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
return sprintf(buf, "%d\n", dahdi_is_sync_master(span));
|
||||
}
|
||||
|
||||
static BUS_ATTR_READER(basechan_show, dev, buf)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
return sprintf(buf, "%d\n", span->chans[0]->channo);
|
||||
}
|
||||
|
||||
static BUS_ATTR_READER(channels_show, dev, buf)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
return sprintf(buf, "%d\n", span->channels);
|
||||
}
|
||||
|
||||
static struct device_attribute span_dev_attrs[] = {
|
||||
__ATTR_RO(name),
|
||||
__ATTR_RO(desc),
|
||||
__ATTR_RO(spantype),
|
||||
__ATTR_RO(local_spanno),
|
||||
__ATTR_RO(alarms),
|
||||
__ATTR_RO(lbo),
|
||||
__ATTR_RO(syncsrc),
|
||||
__ATTR_RO(is_digital),
|
||||
__ATTR_RO(is_sync_master),
|
||||
__ATTR_RO(basechan),
|
||||
__ATTR_RO(channels),
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
static struct driver_attribute dahdi_attrs[] = {
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
static struct bus_type spans_bus_type = {
|
||||
.name = "dahdi_spans",
|
||||
.match = span_match,
|
||||
#ifdef OLD_HOTPLUG_SUPPORT
|
||||
.hotplug = span_hotplug,
|
||||
#else
|
||||
.uevent = span_uevent,
|
||||
#endif
|
||||
.dev_attrs = span_dev_attrs,
|
||||
.drv_attrs = dahdi_attrs,
|
||||
};
|
||||
|
||||
static int span_probe(struct device *dev)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
span_dbg(DEVICES, span, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int span_remove(struct device *dev)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
|
||||
span = dev_to_span(dev);
|
||||
span_dbg(DEVICES, span, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver dahdi_driver = {
|
||||
.name = "generic_lowlevel",
|
||||
.bus = &spans_bus_type,
|
||||
.probe = span_probe,
|
||||
.remove = span_remove,
|
||||
#ifndef OLD_HOTPLUG_SUPPORT
|
||||
.owner = THIS_MODULE
|
||||
#endif
|
||||
};
|
||||
|
||||
static void span_uevent_send(struct dahdi_span *span, enum kobject_action act)
|
||||
{
|
||||
struct kobject *kobj;
|
||||
|
||||
kobj = &span->span_device->kobj;
|
||||
span_dbg(DEVICES, span, "SYFS dev_name=%s action=%d\n",
|
||||
dev_name(span->span_device), act);
|
||||
|
||||
#if defined(OLD_HOTPLUG_SUPPORT_269)
|
||||
{
|
||||
/* Copy from new kernels lib/kobject_uevent.c */
|
||||
static const char *const str[] = {
|
||||
[KOBJ_ADD] "add",
|
||||
[KOBJ_REMOVE] "remove",
|
||||
[KOBJ_CHANGE] "change",
|
||||
[KOBJ_MOUNT] "mount",
|
||||
[KOBJ_UMOUNT] "umount",
|
||||
[KOBJ_OFFLINE] "offline",
|
||||
[KOBJ_ONLINE] "online"
|
||||
};
|
||||
kobject_hotplug(str[act], kobj);
|
||||
}
|
||||
#elif defined(OLD_HOTPLUG_SUPPORT)
|
||||
kobject_hotplug(kobj, act);
|
||||
#else
|
||||
kobject_uevent(kobj, act);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void span_release(struct device *dev)
|
||||
{
|
||||
dahdi_dbg(DEVICES, "%s: %s\n", __func__, dev_name(dev));
|
||||
}
|
||||
|
||||
int dahdi_register_chardev(struct dahdi_chardev *dev)
|
||||
{
|
||||
@@ -78,7 +377,15 @@ EXPORT_SYMBOL(dahdi_unregister_chardev);
|
||||
|
||||
void span_sysfs_remove(struct dahdi_span *span)
|
||||
{
|
||||
struct device *span_device;
|
||||
int x;
|
||||
|
||||
span_dbg(DEVICES, span, "\n");
|
||||
span_device = span->span_device;
|
||||
|
||||
if (!span_device)
|
||||
return;
|
||||
|
||||
for (x = 0; x < span->channels; x++) {
|
||||
struct dahdi_chan *chan = span->chans[x];
|
||||
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
|
||||
@@ -88,13 +395,55 @@ void span_sysfs_remove(struct dahdi_span *span)
|
||||
MKDEV(DAHDI_MAJOR, chan->channo));
|
||||
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
|
||||
}
|
||||
if (!dev_get_drvdata(span_device))
|
||||
return;
|
||||
|
||||
/* Grab an extra reference to the device since we'll still want it
|
||||
* after we've unregistered it */
|
||||
|
||||
get_device(span_device);
|
||||
span_uevent_send(span, KOBJ_OFFLINE);
|
||||
device_unregister(span->span_device);
|
||||
dev_set_drvdata(span_device, NULL);
|
||||
span_device->parent = NULL;
|
||||
put_device(span_device);
|
||||
memset(&span->span_device, 0, sizeof(span->span_device));
|
||||
kfree(span->span_device);
|
||||
span->span_device = NULL;
|
||||
}
|
||||
|
||||
int span_sysfs_create(struct dahdi_span *span)
|
||||
{
|
||||
struct device *span_device;
|
||||
int res = 0;
|
||||
int x;
|
||||
|
||||
if (span->span_device) {
|
||||
WARN_ON(1);
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
span->span_device = kzalloc(sizeof(*span->span_device), GFP_KERNEL);
|
||||
if (!span->span_device)
|
||||
return -ENOMEM;
|
||||
|
||||
span_device = span->span_device;
|
||||
span_dbg(DEVICES, span, "\n");
|
||||
|
||||
span_device->bus = &spans_bus_type;
|
||||
span_device->parent = &span->parent->dev;
|
||||
dev_set_name(span_device, "span-%d", span->spanno);
|
||||
dev_set_drvdata(span_device, span);
|
||||
span_device->release = span_release;
|
||||
res = device_register(span_device);
|
||||
if (res) {
|
||||
span_err(span, "%s: device_register failed: %d\n", __func__,
|
||||
res);
|
||||
kfree(span->span_device);
|
||||
span->span_device = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
for (x = 0; x < span->channels; x++) {
|
||||
struct dahdi_chan *chan = span->chans[x];
|
||||
char chan_name[32];
|
||||
@@ -137,10 +486,248 @@ static struct {
|
||||
unsigned int timer:1;
|
||||
unsigned int channel:1;
|
||||
unsigned int pseudo:1;
|
||||
unsigned int sysfs_driver_registered:1;
|
||||
unsigned int sysfs_spans_bus_type:1;
|
||||
unsigned int dahdi_device_bus_registered:1;
|
||||
} dummy_dev;
|
||||
|
||||
static inline struct dahdi_device *to_ddev(struct device *dev)
|
||||
{
|
||||
return container_of(dev, struct dahdi_device, dev);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t dahdi_device_manufacturer_show(struct device *dev, char *buf)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_manufacturer_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
return sprintf(buf, "%s\n", ddev->manufacturer);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t dahdi_device_type_show(struct device *dev, char *buf)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_type_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
return sprintf(buf, "%s\n", ddev->devicetype);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t dahdi_device_span_count_show(struct device *dev, char *buf)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_span_count_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
unsigned int count = 0;
|
||||
struct list_head *pos;
|
||||
|
||||
list_for_each(pos, &ddev->spans)
|
||||
++count;
|
||||
|
||||
return sprintf(buf, "%d\n", count);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t dahdi_device_hardware_id_show(struct device *dev, char *buf)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_hardware_id_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
|
||||
return sprintf(buf, "%s\n",
|
||||
(ddev->hardware_id) ? ddev->hardware_id : "");
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t
|
||||
dahdi_device_auto_assign(struct device *dev, const char *buf, size_t count)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_auto_assign(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
dahdi_assign_device_spans(ddev);
|
||||
return count;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t
|
||||
dahdi_device_assign_span(struct device *dev, const char *buf, size_t count)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_assign_span(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
struct dahdi_span *span;
|
||||
unsigned int local_span_number;
|
||||
unsigned int desired_spanno;
|
||||
unsigned int desired_basechanno;
|
||||
struct dahdi_device *const ddev = to_ddev(dev);
|
||||
|
||||
ret = sscanf(buf, "%u:%u:%u", &local_span_number, &desired_spanno,
|
||||
&desired_basechanno);
|
||||
if (ret != 3) {
|
||||
dev_notice(dev, "badly formatted input (should be <num>:<num>:<num>)\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (desired_spanno && !desired_basechanno) {
|
||||
dev_notice(dev, "Must set span number AND base chan number\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry(span, &ddev->spans, device_node) {
|
||||
if (local_span_number == local_spanno(span)) {
|
||||
ret = dahdi_assign_span(span, desired_spanno,
|
||||
desired_basechanno, 1);
|
||||
return (ret) ? ret : count;
|
||||
}
|
||||
}
|
||||
dev_notice(dev, "no match for local span number %d\n", local_span_number);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t
|
||||
dahdi_device_unassign_span(struct device *dev, const char *buf, size_t count)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_device_unassign_span(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
int ret;
|
||||
unsigned int local_span_number;
|
||||
struct dahdi_span *span;
|
||||
struct dahdi_device *const ddev = to_ddev(dev);
|
||||
|
||||
ret = sscanf(buf, "%u", &local_span_number);
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
|
||||
ret = -ENODEV;
|
||||
list_for_each_entry(span, &ddev->spans, device_node) {
|
||||
if (local_span_number == local_spanno(span))
|
||||
ret = dahdi_unassign_span(span);
|
||||
}
|
||||
if (-ENODEV == ret) {
|
||||
if (printk_ratelimit()) {
|
||||
dev_info(dev, "'%d' is an invalid local span number.\n",
|
||||
local_span_number);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
return (ret < 0) ? ret : count;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t dahdi_spantype_show(struct device *dev, char *buf)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_spantype_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *ddev = to_ddev(dev);
|
||||
int count = 0;
|
||||
ssize_t total = 0;
|
||||
struct dahdi_span *span;
|
||||
|
||||
/* TODO: Make sure this doesn't overflow the page. */
|
||||
list_for_each_entry(span, &ddev->spans, device_node) {
|
||||
count = sprintf(buf, "%d:%s\n", local_spanno(span), span->spantype);
|
||||
buf += count;
|
||||
total += count;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
|
||||
static ssize_t
|
||||
dahdi_spantype_store(struct device *dev, const char *buf, size_t count)
|
||||
#else
|
||||
static ssize_t
|
||||
dahdi_spantype_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
#endif
|
||||
{
|
||||
struct dahdi_device *const ddev = to_ddev(dev);
|
||||
int ret;
|
||||
struct dahdi_span *span;
|
||||
unsigned int local_span_number;
|
||||
char desired_spantype[80];
|
||||
|
||||
ret = sscanf(buf, "%u:%70s", &local_span_number, desired_spantype);
|
||||
if (ret != 2)
|
||||
return -EINVAL;
|
||||
|
||||
list_for_each_entry(span, &ddev->spans, device_node) {
|
||||
if (local_spanno(span) == local_span_number)
|
||||
break;
|
||||
}
|
||||
|
||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
|
||||
module_printk(KERN_WARNING, "Span %s is already assigned.\n",
|
||||
span->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (local_spanno(span) != local_span_number) {
|
||||
module_printk(KERN_WARNING, "%d is not a valid local span number "
|
||||
"for this device.\n", local_span_number);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!span->ops->set_spantype) {
|
||||
module_printk(KERN_WARNING, "Span %s does not support "
|
||||
"setting type.\n", span->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = span->ops->set_spantype(span, &desired_spantype[0]);
|
||||
return (ret < 0) ? ret : count;
|
||||
}
|
||||
|
||||
static struct device_attribute dahdi_device_attrs[] = {
|
||||
__ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL),
|
||||
__ATTR(type, S_IRUGO, dahdi_device_type_show, NULL),
|
||||
__ATTR(span_count, S_IRUGO, dahdi_device_span_count_show, NULL),
|
||||
__ATTR(hardware_id, S_IRUGO, dahdi_device_hardware_id_show, NULL),
|
||||
__ATTR(auto_assign, S_IWUSR, NULL, dahdi_device_auto_assign),
|
||||
__ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span),
|
||||
__ATTR(unassign_span, S_IWUSR, NULL, dahdi_device_unassign_span),
|
||||
__ATTR(spantype, S_IWUSR | S_IRUGO, dahdi_spantype_show,
|
||||
dahdi_spantype_store),
|
||||
__ATTR_NULL,
|
||||
};
|
||||
|
||||
static struct bus_type dahdi_device_bus = {
|
||||
.name = "dahdi_devices",
|
||||
.dev_attrs = dahdi_device_attrs,
|
||||
};
|
||||
|
||||
void dahdi_sysfs_exit(void)
|
||||
{
|
||||
dahdi_dbg(DEVICES, "SYSFS\n");
|
||||
if (dummy_dev.pseudo) {
|
||||
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
|
||||
DEL_DAHDI_DEV(DAHDI_PSEUDO);
|
||||
@@ -166,7 +753,67 @@ void dahdi_sysfs_exit(void)
|
||||
class_destroy(dahdi_class);
|
||||
dahdi_class = NULL;
|
||||
}
|
||||
if (dummy_dev.sysfs_driver_registered) {
|
||||
dahdi_dbg(DEVICES, "Unregister driver\n");
|
||||
driver_unregister(&dahdi_driver);
|
||||
dummy_dev.sysfs_driver_registered = 0;
|
||||
}
|
||||
if (dummy_dev.sysfs_spans_bus_type) {
|
||||
dahdi_dbg(DEVICES, "Unregister span bus type\n");
|
||||
bus_unregister(&spans_bus_type);
|
||||
dummy_dev.sysfs_spans_bus_type = 0;
|
||||
}
|
||||
unregister_chrdev(DAHDI_MAJOR, "dahdi");
|
||||
|
||||
if (dummy_dev.dahdi_device_bus_registered) {
|
||||
bus_unregister(&dahdi_device_bus);
|
||||
dummy_dev.dahdi_device_bus_registered = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void dahdi_device_release(struct device *dev)
|
||||
{
|
||||
struct dahdi_device *ddev = container_of(dev, struct dahdi_device, dev);
|
||||
kfree(ddev);
|
||||
}
|
||||
|
||||
/**
|
||||
* dahdi_sysfs_add_device - Add the dahdi_device into the sysfs hierarchy.
|
||||
* @ddev: The device to add.
|
||||
* @parent: The physical device that is implementing this device.
|
||||
*
|
||||
* By adding the dahdi_device to the sysfs hierarchy user space can control
|
||||
* how spans are numbered.
|
||||
*
|
||||
*/
|
||||
int dahdi_sysfs_add_device(struct dahdi_device *ddev, struct device *parent)
|
||||
{
|
||||
int ret;
|
||||
struct device *const dev = &ddev->dev;
|
||||
const char *dn;
|
||||
|
||||
dev->parent = parent;
|
||||
dev->bus = &dahdi_device_bus;
|
||||
dn = dev_name(dev);
|
||||
if (!dn || !*dn) {
|
||||
/* Invent default name based on parent */
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
dev_set_name(dev, "%s:%s", parent->bus->name, dev_name(parent));
|
||||
}
|
||||
ret = device_add(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dahdi_sysfs_init_device(struct dahdi_device *ddev)
|
||||
{
|
||||
device_initialize(&ddev->dev);
|
||||
ddev->dev.release = dahdi_device_release;
|
||||
}
|
||||
|
||||
void dahdi_sysfs_unregister_device(struct dahdi_device *ddev)
|
||||
{
|
||||
device_del(&ddev->dev);
|
||||
}
|
||||
|
||||
int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
||||
@@ -174,6 +821,12 @@ int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
||||
int res = 0;
|
||||
void *dev;
|
||||
|
||||
res = bus_register(&dahdi_device_bus);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
dummy_dev.dahdi_device_bus_registered = 1;
|
||||
|
||||
res = register_chrdev(DAHDI_MAJOR, "dahdi", dahdi_fops);
|
||||
if (res) {
|
||||
module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
|
||||
@@ -220,6 +873,20 @@ int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.ctl = 1;
|
||||
res = bus_register(&spans_bus_type);
|
||||
if (res != 0) {
|
||||
dahdi_err("%s: bus_register(%s) failed. Error number %d",
|
||||
__func__, spans_bus_type.name, res);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.sysfs_spans_bus_type = 1;
|
||||
res = driver_register(&dahdi_driver);
|
||||
if (res < 0) {
|
||||
dahdi_err("%s: driver_register(%s) failed. Error number %d",
|
||||
__func__, dahdi_driver.name, res);
|
||||
goto cleanup;
|
||||
}
|
||||
dummy_dev.sysfs_driver_registered = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -34,4 +34,28 @@ 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 */
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#if defined(USE_HIGHRESTIMER)
|
||||
#include <linux/hrtimer.h>
|
||||
#else
|
||||
#include <linux/time.h>
|
||||
#include <linux/timer.h>
|
||||
#endif
|
||||
|
||||
#include <dahdi/kernel.h>
|
||||
@@ -75,6 +75,7 @@ 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;
|
||||
@@ -205,37 +206,44 @@ 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);
|
||||
strlcpy(ztd->span.devicetype, "DAHDI Dummy Timing",
|
||||
sizeof(ztd->span.devicetype));
|
||||
ztd->ddev->devicetype = "DAHDI Dummy Timing";
|
||||
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;
|
||||
if (dahdi_register(&ztd->span, 0)) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
list_add_tail(&ztd->span.device_node, &ztd->ddev->spans);
|
||||
res = dahdi_register_device(ztd->ddev, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (dahdi_dummy_initialize(ztd)) {
|
||||
printk(KERN_ERR "dahdi_dummy: Unable to intialize DAHDI driver\n");
|
||||
res = dahdi_dummy_initialize(ztd);
|
||||
if (res) {
|
||||
printk(KERN_ERR
|
||||
"dahdi_dummy: Unable to intialize DAHDI driver (%d)\n",
|
||||
res);
|
||||
kfree(ztd);
|
||||
return -ENODEV;
|
||||
return res;
|
||||
}
|
||||
|
||||
#if defined(USE_HIGHRESTIMER)
|
||||
@@ -273,7 +281,8 @@ void cleanup_module(void)
|
||||
atomic_set(&shutdown, 1);
|
||||
del_timer_sync(&timer);
|
||||
#endif
|
||||
dahdi_unregister(&ztd->span);
|
||||
dahdi_unregister_device(ztd->ddev);
|
||||
dahdi_free_device(ztd->ddev);
|
||||
kfree(ztd);
|
||||
if (debug)
|
||||
printk(KERN_DEBUG "dahdi_dummy: cleanup() finished\n");
|
||||
|
||||
@@ -385,21 +385,12 @@ 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);
|
||||
}
|
||||
|
||||
@@ -469,7 +460,25 @@ static int _destroy_dynamic(struct dahdi_dynamic_span *dds)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
dahdi_unregister(&d->span);
|
||||
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);
|
||||
|
||||
spin_lock_irqsave(&dspan_lock, flags);
|
||||
list_del_rcu(&d->list);
|
||||
@@ -578,8 +587,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);
|
||||
@@ -604,9 +613,10 @@ 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;
|
||||
sprintf(d->span.name, "DYN/%s/%s", dds->driver, dds->addr);
|
||||
sprintf(d->span.desc, "Dynamic '%s' span at '%s'",
|
||||
dds->driver, dds->addr);
|
||||
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);
|
||||
d->span.deflaw = DAHDI_LAW_MULAW;
|
||||
d->span.flags |= DAHDI_FLAG_RBS;
|
||||
d->span.chans = d->chans;
|
||||
@@ -657,8 +667,12 @@ 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(&d->span, 0)) {
|
||||
if (dahdi_register_device(d->ddev, d->dev)) {
|
||||
printk(KERN_NOTICE "Unable to register span '%s'\n",
|
||||
d->span.name);
|
||||
dynamic_put(d);
|
||||
@@ -761,19 +775,17 @@ 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) {
|
||||
__module_get(d->driver->owner);
|
||||
if (d->driver && d->driver->destroy)
|
||||
d->driver->destroy(d);
|
||||
module_put(d->driver->owner);
|
||||
} else {
|
||||
else
|
||||
WARN_ON(1);
|
||||
}
|
||||
}
|
||||
dahdi_unregister(&d->span);
|
||||
dahdi_unregister_device(d->ddev);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -817,10 +829,13 @@ 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;
|
||||
@@ -831,19 +846,25 @@ static int dahdi_dynamic_init(void)
|
||||
#ifdef ENABLE_TASKLETS
|
||||
tasklet_init(&dahdi_dynamic_tlet, dahdi_dynamic_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);
|
||||
}
|
||||
#endif
|
||||
dahdi_set_dynamic_ioctl(NULL);
|
||||
del_timer_sync(&alarmcheck);
|
||||
/* Must call again in case it was running before and rescheduled
|
||||
* itself. */
|
||||
del_timer(&alarmcheck);
|
||||
printk(KERN_INFO "DAHDI Dynamic Span support unloaded\n");
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ 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;
|
||||
}
|
||||
|
||||
@@ -152,7 +154,7 @@ static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
|
||||
|
||||
spin_lock_irqsave(&zlock, flags);
|
||||
z = dyn->pvt;
|
||||
if (z->dev) {
|
||||
if (z && z->dev) {
|
||||
/* Copy fields to local variables to remove spinlock ASAP */
|
||||
dev = z->dev;
|
||||
memcpy(addr, z->addr, sizeof(z->addr));
|
||||
@@ -191,15 +193,44 @@ static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
|
||||
spin_unlock_irqrestore(&zlock, flags);
|
||||
}
|
||||
|
||||
|
||||
static int ztdeth_flush(void)
|
||||
/**
|
||||
* dahdi_dynamic_flush_work_fn - Flush all pending transactions.
|
||||
*
|
||||
* This function is run in a work queue since we can't guarantee interrupts
|
||||
* will be enabled when we're called, and dev_queue_xmit() requires that
|
||||
* interrupts be enabled.
|
||||
*
|
||||
*/
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
|
||||
static void dahdi_dynamic_flush_work_fn(void *data)
|
||||
#else
|
||||
static void dahdi_dynamic_flush_work_fn(struct work_struct *work)
|
||||
#endif
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
/* Handle all transmissions now */
|
||||
while ((skb = skb_dequeue(&skbs))) {
|
||||
dev_queue_xmit(skb);
|
||||
}
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
|
||||
static DECLARE_WORK(dahdi_dynamic_eth_flush_work,
|
||||
dahdi_dynamic_flush_work_fn, NULL);
|
||||
#else
|
||||
static DECLARE_WORK(dahdi_dynamic_eth_flush_work,
|
||||
dahdi_dynamic_flush_work_fn);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ztdeth_flush - Flush all pending transactions.
|
||||
*
|
||||
* This function is called in interrupt context while processing the master
|
||||
* span.
|
||||
*/
|
||||
static int ztdeth_flush(void)
|
||||
{
|
||||
schedule_work(&dahdi_dynamic_eth_flush_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -284,11 +315,12 @@ static void ztdeth_destroy(struct dahdi_dynamic *dyn)
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
spin_unlock_irqrestore(&zlock, flags);
|
||||
if (cur == z) { /* Successfully removed */
|
||||
dyn->pvt = NULL;
|
||||
printk(KERN_INFO "TDMoE: Removed interface for %s\n", z->span->name);
|
||||
kfree(z);
|
||||
}
|
||||
spin_unlock_irqrestore(&zlock, flags);
|
||||
}
|
||||
|
||||
static int ztdeth_create(struct dahdi_dynamic *dyn, const char *addr)
|
||||
@@ -411,20 +443,27 @@ 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)
|
||||
{
|
||||
dev_remove_pack(&ztdeth_ptype);
|
||||
unregister_netdevice_notifier(&ztdeth_nblock);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
|
||||
flush_scheduled_work();
|
||||
#else
|
||||
cancel_work_sync(&dahdi_dynamic_eth_flush_work);
|
||||
#endif
|
||||
dahdi_dynamic_unregister_driver(&ztd_eth);
|
||||
unregister_netdevice_notifier(&ztdeth_nblock);
|
||||
dev_remove_pack(&ztdeth_ptype);
|
||||
|
||||
skb_queue_purge(&skbs);
|
||||
}
|
||||
|
||||
MODULE_DESCRIPTION("DAHDI Dynamic TDMoE Support");
|
||||
|
||||
@@ -78,10 +78,11 @@ 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 *const d = dyn->pvt;
|
||||
struct dahdi_dynamic_local *d;
|
||||
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);
|
||||
@@ -130,11 +131,12 @@ static int digit2int(char d)
|
||||
|
||||
static void dahdi_dynamic_local_destroy(struct dahdi_dynamic *dyn)
|
||||
{
|
||||
struct dahdi_dynamic_local *d = dyn->pvt;
|
||||
struct dahdi_dynamic_local *d;
|
||||
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;
|
||||
|
||||
@@ -24,14 +24,16 @@
|
||||
|
||||
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.11.0
|
||||
VPMOCT032_VERSION:=1.12.0
|
||||
WCT820_VERSION:=1.76
|
||||
|
||||
FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
|
||||
|
||||
ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032
|
||||
ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-OCT6114-256 FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032 FIRMWARE-TE820
|
||||
|
||||
# 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
|
||||
@@ -42,17 +44,21 @@ ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-TC400M FIRMWARE-
|
||||
# Build a list of firmware package filenames we need
|
||||
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)
|
||||
|
||||
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-064=dahdi-fw-oct6114-064.o)
|
||||
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o)
|
||||
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256.o)
|
||||
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-TC400M=dahdi-fw-tc400m.o)
|
||||
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-HX8=dahdi-fw-hx8.o)
|
||||
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032.o)
|
||||
|
||||
# Force usage of wget, for now
|
||||
DOWNLOAD=wget
|
||||
@@ -123,6 +129,17 @@ ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-12
|
||||
else
|
||||
@echo "Firmware dahdi-fw-oct6114-128.bin is already installed with required version $(OCT6114_128_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-oct6114-256.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-oct6114-256.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION)
|
||||
@install -m 644 dahdi-fw-oct6114-256.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-256-$(OCT6114_256_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-oct6114-256.bin is already installed with required version $(OCT6114_256_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-tc400m.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@@ -156,6 +173,17 @@ ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-
|
||||
else
|
||||
@echo "Firmware dahdi-fw-vpmoct032.bin is already installed with required version $(VPMOCT032_VERSION)"
|
||||
endif
|
||||
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-$(WCT820_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-te820-$(WCT820_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
|
||||
@echo "Installing dahdi-fw-te820.bin to hotplug firmware directories"
|
||||
@install -m 644 dahdi-fw-te820.bin $(DESTDIR)/usr/lib/hotplug/firmware
|
||||
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-*
|
||||
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-te820-$(WCT820_VERSION)
|
||||
@install -m 644 dahdi-fw-te820.bin $(DESTDIR)/lib/firmware
|
||||
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-te820-*
|
||||
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-te820-$(WCT820_VERSION)
|
||||
else
|
||||
@echo "Firmware dahdi-fw-te820.bin is already installed with required version $(WCT820_VERSION)"
|
||||
endif
|
||||
|
||||
# Uninstall any installed dahdi firmware images from hotplug firmware directories
|
||||
hotplug-uninstall:
|
||||
@@ -184,7 +212,17 @@ dahdi-fw-oct6114-128.o: dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz dahdi
|
||||
@echo Making firmware object file for dahdi-fw-oct6114-128.bin
|
||||
./make_firmware_object dahdi-fw-oct6114-128.bin $@
|
||||
|
||||
# Build object file of an oct6114 256 firmware image for linking
|
||||
dahdi-fw-oct6114-256.o: dahdi-fw-oct6114-256-$(OCT6114_256_VERSION).tar.gz dahdi-fw-oct6114-256.bin make_firmware_object
|
||||
@echo Making firmware object file for dahdi-fw-oct6114-256.bin
|
||||
./make_firmware_object dahdi-fw-oct6114-256.bin $@
|
||||
|
||||
# Build object file of a TC400M firmware image for linking
|
||||
dahdi-fw-tc400m.o: dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz dahdi-fw-tc400m.bin make_firmware_object
|
||||
@echo Making firmware object file for dahdi-fw-tc400m.bin
|
||||
./make_firmware_object dahdi-fw-tc400m.bin $@
|
||||
|
||||
# Build object file of a VPMOCT032 firmware image for linking
|
||||
dahdi-fw-vpmoct032.o: dahdi-fw-vpmoct032-$(VPMOCT032_VERSION).tar.gz dahdi-fw-vpmoct032.bin make_firmware_object
|
||||
@echo Making firmware object file for dahdi-fw-vpmoct032.bin
|
||||
./make_firmware_object dahdi-fw-vpmoct032.bin $@
|
||||
|
||||
@@ -397,7 +397,7 @@ $Octasic_Revision: 171 $
|
||||
|
||||
/* Max defines.*/
|
||||
#ifndef cOCT6100_MAX_ECHO_CHANNELS
|
||||
#define cOCT6100_MAX_ECHO_CHANNELS 128
|
||||
#define cOCT6100_MAX_ECHO_CHANNELS 256
|
||||
#endif
|
||||
#define cOCT6100_MAX_TSI_CNCTS 1530
|
||||
#define cOCT6100_MAX_CALLER_ID_PLAYOUT_BUFFERS ( 3328 + 6 )
|
||||
|
||||
@@ -146,6 +146,7 @@ struct encdec
|
||||
|
||||
struct pciradio {
|
||||
struct pci_dev *dev;
|
||||
struct dahdi_device *ddev;
|
||||
struct dahdi_span span;
|
||||
unsigned char ios;
|
||||
int usecount;
|
||||
@@ -1488,7 +1489,7 @@ static int pciradio_initialize(struct pciradio *rad)
|
||||
rad->span.flags = DAHDI_FLAG_RBS;
|
||||
rad->span.ops = &pciradio_span_ops;
|
||||
|
||||
if (dahdi_register(&rad->span, 0)) {
|
||||
if (dahdi_register_device(rad->ddev, &rad->dev->dev)) {
|
||||
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -1777,7 +1778,7 @@ static int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
|
||||
release_region(rad->ioaddr, 0xff);
|
||||
pci_free_consistent(pdev, DAHDI_MAX_CHUNKSIZE * 2 * 2 * 2 * 4, (void *)rad->writechunk, rad->writedma);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
dahdi_unregister(&rad->span);
|
||||
dahdi_free_device(rad->ddev);
|
||||
kfree(rad);
|
||||
return -EIO;
|
||||
|
||||
@@ -1810,7 +1811,7 @@ static int __devinit pciradio_init_one(struct pci_dev *pdev, const struct pci_de
|
||||
|
||||
static void pciradio_release(struct pciradio *rad)
|
||||
{
|
||||
dahdi_unregister(&rad->span);
|
||||
dahdi_unregister_device(rad->ddev);
|
||||
if (rad->freeregion)
|
||||
release_region(rad->ioaddr, 0xff);
|
||||
kfree(rad);
|
||||
|
||||
@@ -97,6 +97,7 @@ 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 */
|
||||
@@ -285,10 +286,6 @@ 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;
|
||||
@@ -322,19 +319,31 @@ 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;
|
||||
if (dahdi_register(s, 0)) {
|
||||
printk(KERN_ERR "Unable to register span %s\n", s->name);
|
||||
goto error_exit;
|
||||
}
|
||||
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;
|
||||
}
|
||||
writew(PLX_INTENA, &tor->plx[INTCSR]); /* enable PLX interrupt */
|
||||
|
||||
@@ -342,14 +351,6 @@ 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)
|
||||
@@ -365,6 +366,8 @@ 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);
|
||||
}
|
||||
|
||||
@@ -631,7 +634,6 @@ 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)
|
||||
@@ -641,11 +643,7 @@ static void __devexit tor2_remove(struct pci_dev *pdev)
|
||||
writeb(0, &tor->mem8[LEDREG]);
|
||||
writew(0, &tor->plx[INTCSR]);
|
||||
free_irq(tor->irq, tor);
|
||||
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);
|
||||
}
|
||||
dahdi_unregister_device(tor->ddev);
|
||||
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);
|
||||
|
||||
@@ -126,8 +126,8 @@ static int vpmadt032_getreg_full_return(struct vpmadt032 *vpm, int pagechange,
|
||||
unsigned long ret;
|
||||
BUG_ON(!cmd);
|
||||
|
||||
/* We'll wait for 200ms */
|
||||
ret = wait_for_completion_timeout(&cmd->complete, HZ/5);
|
||||
/* We'll wait for 2s */
|
||||
ret = wait_for_completion_timeout(&cmd->complete, HZ*2);
|
||||
if (unlikely(!ret)) {
|
||||
spin_lock_irqsave(&vpm->list_lock, flags);
|
||||
list_del(&cmd->node);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#ifndef _GPAKCUST_H /* prevent multiple inclusion */
|
||||
#define _GPAKCUST_H
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
@@ -2,4 +2,17 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += dahdi_voicebus.o
|
||||
|
||||
dahdi_voicebus-objs := voicebus.o GpakCust.o GpakApi.o voicebus_net.o vpmoct.o
|
||||
|
||||
EXTRA_CFLAGS := -I$(src)/.. -Wno-undef
|
||||
FIRM_DIR := ../firmware
|
||||
|
||||
ifneq ($(HOTPLUG_FIRMWARE),yes)
|
||||
dahdi_voicebus-objs += $(FIRM_DIR)/dahdi-fw-vpmoct032.o
|
||||
$(warning WARNING: You are compiling firmware into voicebus.ko which is not available under the terms of the GPL. It may be a violation of the GPL to distribute the resulting image since it combines both GPL and non-GPL work. You should consult a lawyer of your own before distributing such an image.)
|
||||
else
|
||||
EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -I$(src)/.. -Wno-undef
|
||||
|
||||
$(obj)/$(FIRM_DIR)/dahdi-fw-vpmoct032.o: $(obj)/voicebus.o
|
||||
$(MAKE) -C $(obj)/$(FIRM_DIR) dahdi-fw-vpmoct032.o
|
||||
|
||||
|
||||
@@ -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(NULL, 0);
|
||||
dahdi_register_device(NULL, NULL);
|
||||
spin_lock_init(&loader_list_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,15 @@
|
||||
* (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
|
||||
|
||||
@@ -72,7 +72,7 @@ static int _vpmoct_read(struct vpmoct *vpm, u8 address,
|
||||
list_del(&cmd->node);
|
||||
spin_unlock_irqrestore(&vpm->list_lock, flags);
|
||||
kfree(cmd);
|
||||
dev_err(vpm->dev, "vpmoct_read_byte cmd timed out :O(\n");
|
||||
dev_err(vpm->dev, "vpmoct_read_byte cmd timed out\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -443,6 +443,47 @@ static void vpmoct_set_defaults(struct vpmoct *vpm)
|
||||
vpmoct_write_dword(vpm, 0x30, 0);
|
||||
}
|
||||
|
||||
static const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin";
|
||||
#if defined(HOTPLUG_FIRMWARE)
|
||||
static int
|
||||
vpmoct_request_firmware(const struct firmware **fw, struct device *dev)
|
||||
{
|
||||
return request_firmware(fw, FIRMWARE_NAME, dev);
|
||||
}
|
||||
|
||||
static void vpmoct_release_firmware(const struct firmware *fw)
|
||||
{
|
||||
release_firmware(fw);
|
||||
}
|
||||
#else
|
||||
static int
|
||||
vpmoct_request_firmware(const struct firmware **fw_p, struct device *dev)
|
||||
{
|
||||
struct firmware *fw;
|
||||
extern void _binary_dahdi_fw_vpmoct032_bin_size;
|
||||
extern u8 _binary_dahdi_fw_vpmoct032_bin_start[];
|
||||
|
||||
*fw_p = fw = kzalloc(sizeof(*fw), GFP_KERNEL);
|
||||
if (!fw)
|
||||
return -ENOMEM;
|
||||
|
||||
fw->data = _binary_dahdi_fw_vpmoct032_bin_start;
|
||||
/* Yes... this is weird. objcopy gives us a symbol containing
|
||||
the size of the firmware, not a pointer a variable containing the
|
||||
size. The only way we can get the value of the symbol is to take
|
||||
its address, so we define it as a pointer and then cast that value
|
||||
to the proper type. */
|
||||
fw->size = (size_t) &_binary_dahdi_fw_vpmoct032_bin_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vpmoct_release_firmware(const struct firmware *fw)
|
||||
{
|
||||
kfree(fw);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* vpmoct_load_flash - Check the current flash version and possibly load.
|
||||
* @vpm: The VPMOCT032 module to check / load.
|
||||
@@ -463,10 +504,9 @@ static void vpmoct_load_flash(struct work_struct *data)
|
||||
const struct firmware *fw;
|
||||
const struct vpmoct_header *header;
|
||||
char serial[VPMOCT_SERIAL_SIZE+1];
|
||||
const char *const FIRMWARE_NAME = "dahdi-fw-vpmoct032.bin";
|
||||
int i;
|
||||
|
||||
res = request_firmware(&fw, FIRMWARE_NAME, vpm->dev);
|
||||
res = vpmoct_request_firmware(&fw, vpm->dev);
|
||||
if (res) {
|
||||
dev_warn(vpm->dev,
|
||||
"vpmoct: Failed to load firmware from userspace! %d\n",
|
||||
@@ -505,7 +545,7 @@ static void vpmoct_load_flash(struct work_struct *data)
|
||||
FIRMWARE_NAME);
|
||||
|
||||
/* Just use the old version of the fimware. */
|
||||
release_firmware(fw);
|
||||
vpmoct_release_firmware(fw);
|
||||
vpmoct_set_defaults(vpm);
|
||||
vpmoct_load_complete(work, true);
|
||||
return;
|
||||
@@ -514,7 +554,7 @@ static void vpmoct_load_flash(struct work_struct *data)
|
||||
if (vpm->minor == header->minor &&
|
||||
vpm->major == header->major) {
|
||||
/* Proper version is running */
|
||||
release_firmware(fw);
|
||||
vpmoct_release_firmware(fw);
|
||||
vpmoct_set_defaults(vpm);
|
||||
vpmoct_load_complete(work, true);
|
||||
return;
|
||||
@@ -548,14 +588,14 @@ static void vpmoct_load_flash(struct work_struct *data)
|
||||
if (vpmoct_check_firmware_crc(vpm, fw->size-VPMOCT_FIRM_HEADER_LEN*2,
|
||||
header->major, header->minor))
|
||||
goto error;
|
||||
release_firmware(fw);
|
||||
vpmoct_release_firmware(fw);
|
||||
vpmoct_set_defaults(vpm);
|
||||
vpmoct_load_complete(work, true);
|
||||
return;
|
||||
|
||||
error:
|
||||
dev_info(vpm->dev, "Unable to load firmware\n");
|
||||
release_firmware(fw);
|
||||
vpmoct_release_firmware(fw);
|
||||
/* TODO: Should we disable module if the firmware doesn't load? */
|
||||
vpmoct_load_complete(work, false);
|
||||
return;
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/device.h> /* dev_err() */
|
||||
#include <linux/interrupt.h>
|
||||
#include <asm/system.h> /* cli(), *_flags */
|
||||
#include <asm/uaccess.h> /* copy_*_user */
|
||||
#include <linux/workqueue.h> /* work_struct */
|
||||
#include <linux/timer.h> /* timer_struct */
|
||||
@@ -2205,7 +2204,7 @@ static const char *b4xxp_echocan_name(const struct dahdi_chan *chan)
|
||||
{
|
||||
struct b4xxp_span *bspan = container_of(chan->span, struct b4xxp_span,
|
||||
span);
|
||||
if (bspan->parent->card_type == B410P)
|
||||
if (vpmsupport && (B410P == bspan->parent->card_type))
|
||||
return "LASVEGAS2";
|
||||
return NULL;
|
||||
}
|
||||
@@ -2475,7 +2474,6 @@ static void init_spans(struct b4xxp *b4)
|
||||
bspan = &b4->spans[i];
|
||||
bspan->parent = b4;
|
||||
|
||||
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;
|
||||
@@ -2494,11 +2492,6 @@ 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 */
|
||||
@@ -2930,14 +2923,27 @@ 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++) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -2973,10 +2979,7 @@ 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:
|
||||
while (x) {
|
||||
dahdi_unregister(&b4->spans[x].span);
|
||||
x--;
|
||||
};
|
||||
dahdi_unregister_device(b4->ddev);
|
||||
|
||||
b4xxp_init_stage1(b4); /* full reset, re-init to "no-irq" state */
|
||||
free_irq(pdev->irq, b4);
|
||||
@@ -2997,6 +3000,8 @@ 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:
|
||||
@@ -3011,14 +3016,11 @@ 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;
|
||||
|
||||
for (i=b4->numspans - 1; i >= 0; i--) {
|
||||
dahdi_unregister(&b4->spans[i].span);
|
||||
}
|
||||
dahdi_unregister_device(b4->ddev);
|
||||
|
||||
b4xxp_init_stage1(b4);
|
||||
remove_sysfs_files(b4);
|
||||
@@ -3033,6 +3035,8 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -474,6 +474,7 @@ 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 */
|
||||
|
||||
@@ -135,6 +135,7 @@ 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;
|
||||
@@ -647,19 +648,24 @@ 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);
|
||||
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->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;
|
||||
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
|
||||
@@ -668,7 +674,8 @@ static int wcfxo_initialize(struct wcfxo *wc)
|
||||
|
||||
wc->chan->pvt = wc;
|
||||
wc->span.ops = &wcfxo_span_ops;
|
||||
if (dahdi_register(&wc->span, 0)) {
|
||||
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
|
||||
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
|
||||
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -976,7 +983,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(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
free_irq(pdev->irq, wc);
|
||||
|
||||
/* Reset PCI chip and registers */
|
||||
@@ -984,6 +991,8 @@ 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;
|
||||
}
|
||||
@@ -995,9 +1004,11 @@ static int __devinit wcfxo_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
|
||||
static void wcfxo_release(struct wcfxo *wc)
|
||||
{
|
||||
dahdi_unregister(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -159,6 +159,7 @@ 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 */
|
||||
};
|
||||
|
||||
@@ -272,10 +273,11 @@ static void t1xxp_release(struct t1xxp *wc)
|
||||
{
|
||||
unsigned int x;
|
||||
|
||||
dahdi_unregister(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
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");
|
||||
}
|
||||
@@ -770,14 +772,20 @@ 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->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->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.chans = wc->chans;
|
||||
wc->span.flags = DAHDI_FLAG_RBS;
|
||||
if (wc->ise1) {
|
||||
@@ -801,7 +809,8 @@ static int t1xxp_software_init(struct t1xxp *wc)
|
||||
wc->chans[x]->chanpos = x + 1;
|
||||
}
|
||||
wc->span.ops = &t1xxp_span_ops;
|
||||
if (dahdi_register(&wc->span, 0)) {
|
||||
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
|
||||
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
|
||||
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -908,10 +917,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->span.irqmisses++;
|
||||
wc->ddev->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->span.irqmisses++;
|
||||
wc->ddev->irqmisses++;
|
||||
}
|
||||
for (y=0;y<DAHDI_CHUNKSIZE;y++) {
|
||||
for (x=0;x<wc->span.channels;x++) {
|
||||
|
||||
@@ -17,7 +17,8 @@ endif
|
||||
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
|
||||
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.o $(FIRM_DIR)/dahdi-fw-oct6114-256.o
|
||||
$(warning WARNING: You are compiling firmware into wct4xxp.ko which is not available under the terms of the GPL. It may be a violation of the GPL to distribute the resulting image since it combines both GPL and non-GPL work. You should consult a lawyer of your own before distributing such an image.)
|
||||
endif
|
||||
|
||||
$(obj)/$(FIRM_DIR)/dahdi-fw-oct6114-064.o: $(obj)/base.o
|
||||
@@ -25,3 +26,6 @@ $(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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -172,9 +172,9 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
|
||||
|
||||
struct vpm450m {
|
||||
tPOCT6100_INSTANCE_API pApiInstance;
|
||||
UINT32 aulEchoChanHndl[128];
|
||||
int chanflags[128];
|
||||
int ecmode[128];
|
||||
UINT32 aulEchoChanHndl[256];
|
||||
int chanflags[256];
|
||||
int ecmode[256];
|
||||
int numchans;
|
||||
};
|
||||
|
||||
@@ -422,6 +422,8 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
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;
|
||||
|
||||
@@ -467,15 +469,22 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
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
|
||||
@@ -507,7 +516,11 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
kfree(ChannelOpen);
|
||||
return NULL;
|
||||
}
|
||||
for (x = 0; x < ARRAY_SIZE(vpm450m->aulEchoChanHndl); x++) {
|
||||
|
||||
sout_stream = (8 == numspans) ? 29 : 2;
|
||||
rout_stream = (8 == numspans) ? 24 : 3;
|
||||
|
||||
for (x = 0; x < ((8 == numspans) ? 256 : 128); 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)) {
|
||||
@@ -515,7 +528,7 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
* therefore, the lower 2 bits tell us which span this
|
||||
* timeslot/channel
|
||||
*/
|
||||
if (isalaw[x & 0x03])
|
||||
if (isalaw[x & mask])
|
||||
law = cOCT6100_PCM_A_LAW;
|
||||
else
|
||||
law = cOCT6100_PCM_U_LAW;
|
||||
@@ -529,11 +542,13 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
ChannelOpen->TdmConfig.ulSinStream = 1;
|
||||
ChannelOpen->TdmConfig.ulSinTimeslot = x;
|
||||
ChannelOpen->TdmConfig.ulSoutPcmLaw = law;
|
||||
ChannelOpen->TdmConfig.ulSoutStream = 2;
|
||||
ChannelOpen->TdmConfig.ulSoutStream = sout_stream;
|
||||
ChannelOpen->TdmConfig.ulSoutTimeslot = x;
|
||||
#if 1
|
||||
ChannelOpen->TdmConfig.ulRoutPcmLaw = law;
|
||||
ChannelOpen->TdmConfig.ulRoutStream = 3;
|
||||
ChannelOpen->TdmConfig.ulRoutStream = rout_stream;
|
||||
ChannelOpen->TdmConfig.ulRoutTimeslot = x;
|
||||
#endif
|
||||
ChannelOpen->VqeConfig.fEnableNlp = TRUE;
|
||||
ChannelOpen->VqeConfig.fRinDcOffsetRemoval = TRUE;
|
||||
ChannelOpen->VqeConfig.fSinDcOffsetRemoval = TRUE;
|
||||
@@ -543,7 +558,7 @@ struct vpm450m *init_vpm450m(void *wc, int *isalaw, int numspans, const struct f
|
||||
|
||||
ulResult = Oct6100ChannelOpen(vpm450m->pApiInstance, ChannelOpen);
|
||||
if (ulResult != GENERIC_OK) {
|
||||
printk(KERN_NOTICE "Failed to open channel %d!\n", x);
|
||||
printk(KERN_NOTICE "Failed to open channel %d %x!\n", x, ulResult);
|
||||
continue;
|
||||
}
|
||||
for (y = 0; y < ARRAY_SIZE(tones); y++) {
|
||||
|
||||
@@ -54,6 +54,12 @@
|
||||
#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
|
||||
@@ -76,6 +82,13 @@
|
||||
#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
|
||||
@@ -113,6 +126,11 @@ 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
|
||||
@@ -120,5 +138,7 @@ struct t4_regs {
|
||||
#define T4_CHANGE_LATENCY 4
|
||||
#define T4_IGNORE_LATENCY 5
|
||||
|
||||
#define WCT4_GET_REGS _IOW (DAHDI_CODE, 60, struct t4_regs)
|
||||
#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)
|
||||
|
||||
|
||||
@@ -73,20 +73,6 @@
|
||||
dev_info(&(wc)->pdev->dev, _fmt, ## _args); \
|
||||
} \
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
#ifndef WARN_ON_ONCE
|
||||
#define WARN_ON_ONCE(__condition) do { \
|
||||
static int __once = 1; \
|
||||
if (unlikely(__condition)) { \
|
||||
if (__once) { \
|
||||
__once = 0; \
|
||||
WARN_ON(0); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
|
||||
/* also added in RHEL kernels with the OpenInfiniband backport: */
|
||||
#if LINUX_VERSION_CODE != KERNEL_VERSION(2, 6, 9) || !defined(DEFINE_SPINLOCK)
|
||||
@@ -488,6 +474,7 @@ wctc4xxp_skb_to_cmd(struct wcdte *wc, const struct sk_buff *skb)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
|
||||
static void
|
||||
wctc4xxp_net_set_multi(struct net_device *netdev)
|
||||
{
|
||||
@@ -495,6 +482,15 @@ wctc4xxp_net_set_multi(struct net_device *netdev)
|
||||
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
|
||||
__func__, netdev->promiscuity);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
wctc4xxp_set_rx_mode(struct net_device *netdev)
|
||||
{
|
||||
struct wcdte *wc = wcdte_from_netdev(netdev);
|
||||
DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n",
|
||||
__func__, netdev->promiscuity);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
wctc4xxp_net_up(struct net_device *netdev)
|
||||
@@ -658,7 +654,11 @@ wctc4xxp_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
|
||||
#ifdef HAVE_NET_DEVICE_OPS
|
||||
static const struct net_device_ops wctc4xxp_netdev_ops = {
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)
|
||||
.ndo_set_multicast_list = &wctc4xxp_net_set_multi,
|
||||
#else
|
||||
.ndo_set_rx_mode = &wctc4xxp_set_rx_mode,
|
||||
#endif
|
||||
.ndo_open = &wctc4xxp_net_up,
|
||||
.ndo_stop = &wctc4xxp_net_down,
|
||||
.ndo_start_xmit = &wctc4xxp_net_hard_start_xmit,
|
||||
@@ -2158,12 +2158,13 @@ wctc4xxp_write(struct file *file, const char __user *frame,
|
||||
}
|
||||
|
||||
if (DAHDI_FORMAT_G723_1 == dtc->srcfmt) {
|
||||
if ((G723_5K_BYTES != count) && (G723_6K_BYTES != count)) {
|
||||
if ((G723_5K_BYTES != count) && (G723_6K_BYTES != count) &&
|
||||
(G723_SID_BYTES != count)) {
|
||||
DTE_DEBUG(DTE_DEBUG_GENERAL,
|
||||
"Trying to transcode packet into G723 format " \
|
||||
"that is %Zu bytes instead of the expected " \
|
||||
"%d/%d bytes.\n", count, G723_5K_BYTES,
|
||||
G723_6K_BYTES);
|
||||
"%d/%d/%d bytes.\n", count, G723_5K_BYTES,
|
||||
G723_6K_BYTES, G723_SID_BYTES);
|
||||
return -EINVAL;
|
||||
}
|
||||
cpvt->timestamp += G723_SAMPLES;
|
||||
|
||||
@@ -205,6 +205,7 @@ struct wctdm {
|
||||
struct pci_dev *dev;
|
||||
char *variety;
|
||||
struct dahdi_span span;
|
||||
struct dahdi_device *ddev;
|
||||
unsigned char ios;
|
||||
int usecount;
|
||||
unsigned int intcount;
|
||||
@@ -2362,13 +2363,26 @@ 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);
|
||||
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->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;
|
||||
|
||||
if (alawoverride) {
|
||||
printk(KERN_INFO "ALAW override parameter detected. Device will be operating in ALAW\n");
|
||||
wc->span.deflaw = DAHDI_LAW_ALAW;
|
||||
@@ -2384,12 +2398,15 @@ 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;
|
||||
|
||||
if (dahdi_register(&wc->span, 0)) {
|
||||
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
|
||||
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
|
||||
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;
|
||||
@@ -2677,7 +2694,9 @@ 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(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
kfree(wc->ddev->location);
|
||||
dahdi_free_device(wc->ddev);
|
||||
kfree(wc);
|
||||
return -EIO;
|
||||
|
||||
@@ -2708,10 +2727,14 @@ static int __devinit wctdm_init_one(struct pci_dev *pdev, const struct pci_devic
|
||||
|
||||
static void wctdm_release(struct wctdm *wc)
|
||||
{
|
||||
dahdi_unregister(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,6 @@
|
||||
* \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 */
|
||||
@@ -85,7 +84,6 @@
|
||||
|
||||
#define NUM_CAL_REGS 12
|
||||
|
||||
#define ISR_COMMANDS 2
|
||||
#define QRV_DEBOUNCETIME 20
|
||||
|
||||
#define VPM150M_HPI_CONTROL 0x00
|
||||
@@ -107,10 +105,30 @@ struct calregs {
|
||||
|
||||
enum battery_state {
|
||||
BATTERY_UNKNOWN = 0,
|
||||
BATTERY_DEBOUNCING_PRESENT,
|
||||
BATTERY_DEBOUNCING_PRESENT_ALARM,
|
||||
BATTERY_PRESENT,
|
||||
BATTERY_DEBOUNCING_LOST,
|
||||
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;
|
||||
@@ -146,29 +164,26 @@ struct wctdm_chan {
|
||||
};
|
||||
|
||||
struct fxo {
|
||||
int wasringing;
|
||||
int lastrdtx;
|
||||
int lastrdtx_count;
|
||||
int ringdebounce;
|
||||
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 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 {
|
||||
int oldrxhook;
|
||||
int debouncehook;
|
||||
int lastrxhook;
|
||||
int debounce;
|
||||
int ohttimer;
|
||||
u8 oht_active:1;
|
||||
u8 off_hook:1;
|
||||
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
|
||||
@@ -180,13 +195,18 @@ struct fxs {
|
||||
* voicebus ISR.
|
||||
*/
|
||||
int lasttxhook;
|
||||
int oppending_ms;
|
||||
u8 linefeed_control_shadow;
|
||||
u8 hook_state_shadow;
|
||||
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 {
|
||||
@@ -203,6 +223,7 @@ struct qrv {
|
||||
int radmode;
|
||||
signed short rxgain;
|
||||
signed short txgain;
|
||||
u8 isrshadow[3];
|
||||
};
|
||||
|
||||
enum module_type {
|
||||
@@ -215,7 +236,7 @@ enum module_type {
|
||||
};
|
||||
|
||||
struct wctdm_module {
|
||||
union {
|
||||
union modtypes {
|
||||
struct fxo fxo;
|
||||
struct fxs fxs;
|
||||
struct qrv qrv;
|
||||
@@ -227,7 +248,6 @@ struct wctdm_module {
|
||||
struct list_head active_cmds;
|
||||
u8 offsets[3];
|
||||
u8 subaddr;
|
||||
u8 isrshadow[ISR_COMMANDS];
|
||||
u8 card;
|
||||
|
||||
enum module_type type;
|
||||
@@ -242,7 +262,7 @@ struct wctdm {
|
||||
spinlock_t frame_list_lock;
|
||||
struct list_head frame_list;
|
||||
|
||||
unsigned int intcount;
|
||||
unsigned long framecount;
|
||||
unsigned char txident;
|
||||
unsigned char rxident;
|
||||
|
||||
@@ -277,6 +297,7 @@ 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)
|
||||
|
||||
@@ -174,6 +174,7 @@ 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 */
|
||||
};
|
||||
@@ -340,10 +341,12 @@ static void t1xxp_release(struct t1 *wc)
|
||||
{
|
||||
unsigned int x;
|
||||
|
||||
dahdi_unregister(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
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");
|
||||
}
|
||||
@@ -976,15 +979,21 @@ 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->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->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;
|
||||
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (unchannelized)
|
||||
wc->span.channels = 32;
|
||||
@@ -1011,7 +1020,8 @@ static int t1xxp_software_init(struct t1 *wc)
|
||||
wc->chans[x]->chanpos = x + 1;
|
||||
}
|
||||
wc->span.ops = &t1xxp_span_ops;
|
||||
if (dahdi_register(&wc->span, 0)) {
|
||||
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
|
||||
if (dahdi_register_device(wc->ddev, &wc->dev->dev)) {
|
||||
printk(KERN_NOTICE "Unable to register span with DAHDI\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -1118,10 +1128,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->span.irqmisses++;
|
||||
wc->ddev->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->span.irqmisses++;
|
||||
wc->ddev->irqmisses++;
|
||||
}
|
||||
for (y=0;y<DAHDI_CHUNKSIZE;y++) {
|
||||
for (x=0;x<wc->span.channels;x++) {
|
||||
|
||||
@@ -55,13 +55,18 @@
|
||||
#error VOICEBUS_SFRAME_SIZE != SFRAME_SIZE
|
||||
#endif
|
||||
|
||||
#ifndef pr_fmt
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
#endif
|
||||
|
||||
static int debug;
|
||||
static int j1mode = 0;
|
||||
static int alarmdebounce = 2500; /* LOF/LFA def to 2.5s AT&T TR54016*/
|
||||
static int losalarmdebounce = 2500; /* LOS def to 2.5s AT&T TR54016*/
|
||||
static int aisalarmdebounce = 2500; /* AIS(blue) def to 2.5s AT&T TR54016*/
|
||||
static int yelalarmdebounce = 500; /* RAI(yellow) def to 0.5s AT&T devguide */
|
||||
static int t1e1override = -1;
|
||||
static int t1e1override = -1; /* deprecated */
|
||||
static char *default_linemode = "auto"; /* 'auto', 'e1', or 't1' */
|
||||
static int latency = VOICEBUS_DEFAULT_LATENCY;
|
||||
static unsigned int max_latency = VOICEBUS_DEFAULT_MAXLATENCY;
|
||||
static int vpmsupport = 1;
|
||||
@@ -94,6 +99,11 @@ static const struct t1_desc te120p = {"Wildcard TE120P"};
|
||||
static const struct t1_desc te122 = {"Wildcard TE122"};
|
||||
static const struct t1_desc te121 = {"Wildcard TE121"};
|
||||
|
||||
static inline bool is_pcie(const struct t1 *t1)
|
||||
{
|
||||
return (0 == strcmp(t1->variety, te121.name));
|
||||
}
|
||||
|
||||
/* names of HWEC modules */
|
||||
static const char *vpmadt032_name = "VPMADT032";
|
||||
static const char *vpmoct_name = "VPMOCT032";
|
||||
@@ -750,7 +760,7 @@ static void __t1xxp_set_clear(struct t1 *wc)
|
||||
/* Calculate all states on all 24 channels using the channel
|
||||
flags, then write all 3 clear channel registers at once */
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
for (i = 0; i < wc->span.channels; i++) {
|
||||
offset = i/8;
|
||||
if (wc->span.chans[i]->flags & DAHDI_FLAG_CLEAR)
|
||||
reg[offset] |= 1 << (7 - (i % 8));
|
||||
@@ -771,19 +781,31 @@ static void __t1xxp_set_clear(struct t1 *wc)
|
||||
t1_info(wc, "Unable to set clear/rbs mode!\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* _t1_free_channels - Free the memory allocated for the channels.
|
||||
*
|
||||
* Must be called with wc->reglock held.
|
||||
*
|
||||
*/
|
||||
static void _t1_free_channels(struct t1 *wc)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < ARRAY_SIZE(wc->chans); x++) {
|
||||
kfree(wc->chans[x]);
|
||||
kfree(wc->ec[x]);
|
||||
wc->chans[x] = NULL;
|
||||
wc->ec[x] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_wc(struct t1 *wc)
|
||||
{
|
||||
unsigned int x;
|
||||
unsigned long flags;
|
||||
struct command *cmd;
|
||||
LIST_HEAD(list);
|
||||
|
||||
for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
|
||||
kfree(wc->chans[x]);
|
||||
kfree(wc->ec[x]);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
_t1_free_channels(wc);
|
||||
list_splice_init(&wc->active_cmds, &list);
|
||||
list_splice_init(&wc->pending_cmds, &list);
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
@@ -803,14 +825,14 @@ static void free_wc(struct t1 *wc)
|
||||
}
|
||||
#endif
|
||||
|
||||
kfree(wc->ddev->location);
|
||||
kfree(wc->ddev->devicetype);
|
||||
dahdi_free_device(wc->ddev);
|
||||
kfree(wc);
|
||||
}
|
||||
|
||||
static void t4_serial_setup(struct t1 *wc)
|
||||
{
|
||||
t1_info(wc, "Setting up global serial parameters for %s\n",
|
||||
((wc->spantype == TYPE_E1) ? "E1" : "T1"));
|
||||
|
||||
t1_setreg(wc, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
|
||||
t1_setreg(wc, 0x08, 0x05); /* IPC: Interrupt push/pull active low */
|
||||
|
||||
@@ -1004,12 +1026,12 @@ static void t1_configure_e1(struct t1 *wc, int lineconfig)
|
||||
t1_info(wc, "Span configured for %s/%s%s\n", framing, line, crc4);
|
||||
}
|
||||
|
||||
static void t1xxp_framer_start(struct t1 *wc, struct dahdi_span *span)
|
||||
static void t1xxp_framer_start(struct t1 *wc)
|
||||
{
|
||||
if (wc->spantype == TYPE_E1) { /* if this is an E1 card */
|
||||
t1_configure_e1(wc, span->lineconfig);
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
t1_configure_e1(wc, wc->span.lineconfig);
|
||||
} else { /* is a T1 card */
|
||||
t1_configure_t1(wc, span->lineconfig, span->txlevel);
|
||||
t1_configure_t1(wc, wc->span.lineconfig, wc->span.txlevel);
|
||||
__t1xxp_set_clear(wc);
|
||||
}
|
||||
|
||||
@@ -1018,14 +1040,28 @@ static void t1xxp_framer_start(struct t1 *wc, struct dahdi_span *span)
|
||||
|
||||
static void set_span_devicetype(struct t1 *wc)
|
||||
{
|
||||
strncpy(wc->span.devicetype, wc->variety,
|
||||
sizeof(wc->span.devicetype) - 1);
|
||||
const char *olddevicetype;
|
||||
olddevicetype = wc->ddev->devicetype;
|
||||
|
||||
#if defined(VPM_SUPPORT)
|
||||
if (wc->vpmadt032)
|
||||
strncat(wc->span.devicetype, " (VPMADT032)",
|
||||
sizeof(wc->span.devicetype) - 1);
|
||||
if (wc->vpmadt032) {
|
||||
wc->ddev->devicetype = kasprintf(GFP_KERNEL,
|
||||
"%s (VPMADT032)", wc->variety);
|
||||
} else if (wc->vpmoct) {
|
||||
wc->ddev->devicetype = kasprintf(GFP_KERNEL,
|
||||
"%s (VPMOCT032)", wc->variety);
|
||||
} else {
|
||||
wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s", wc->variety);
|
||||
}
|
||||
#else
|
||||
wc->ddev->devicetype = kasprintf(GFP_KERNEL, "%s", wc->variety);
|
||||
#endif
|
||||
|
||||
/* On the off chance that we were able to allocate it previously. */
|
||||
if (!wc->ddev->devicetype)
|
||||
wc->ddev->devicetype = olddevicetype;
|
||||
else
|
||||
kfree(olddevicetype);
|
||||
}
|
||||
|
||||
static int t1xxp_startup(struct file *file, struct dahdi_span *span)
|
||||
@@ -1046,7 +1082,7 @@ static int t1xxp_startup(struct file *file, struct dahdi_span *span)
|
||||
#endif
|
||||
|
||||
/* Reset framer with proper parameters and start */
|
||||
t1xxp_framer_start(wc, span);
|
||||
t1xxp_framer_start(wc);
|
||||
debug_printk(wc, 1, "Calling startup (flags is %lu)\n", span->flags);
|
||||
|
||||
return 0;
|
||||
@@ -1086,7 +1122,7 @@ static int t1xxp_chanconfig(struct file *file,
|
||||
}
|
||||
|
||||
if (test_bit(DAHDI_FLAGBIT_RUNNING, &chan->span->flags) &&
|
||||
(wc->spantype != TYPE_E1)) {
|
||||
dahdi_is_t1_span(&wc->span)) {
|
||||
__t1xxp_set_clear(wc);
|
||||
}
|
||||
return 0;
|
||||
@@ -1101,7 +1137,7 @@ static int t1xxp_rbsbits(struct dahdi_chan *chan, int bits)
|
||||
|
||||
debug_printk(wc, 2, "Setting bits to %d on channel %s\n",
|
||||
bits, chan->name);
|
||||
if (wc->spantype == TYPE_E1) { /* do it E1 way */
|
||||
if (dahdi_is_e1_span(&wc->span)) { /* do it E1 way */
|
||||
if (chan->chanpos == 16)
|
||||
return 0;
|
||||
|
||||
@@ -1154,7 +1190,7 @@ static inline void t1_check_sigbits(struct t1 *wc)
|
||||
|
||||
if (!(test_bit(DAHDI_FLAGBIT_RUNNING, &wc->span.flags)))
|
||||
return;
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
for (i = 0; i < 15; i++) {
|
||||
a = t1_getreg(wc, 0x71 + i);
|
||||
if (a > -1) {
|
||||
@@ -1249,7 +1285,7 @@ static void t1xxp_maint_work(struct work_struct *work)
|
||||
int reg = 0;
|
||||
int cmd = w->cmd;
|
||||
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
switch (cmd) {
|
||||
case DAHDI_MAINT_NONE:
|
||||
t1_info(wc, "Clearing all maint modes\n");
|
||||
@@ -1321,7 +1357,7 @@ static int t1xxp_maint(struct dahdi_span *span, int cmd)
|
||||
struct maint_work_struct *work;
|
||||
struct t1 *wc = container_of(span, struct t1, span);
|
||||
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
switch (cmd) {
|
||||
case DAHDI_MAINT_NONE:
|
||||
case DAHDI_MAINT_LOCALLOOP:
|
||||
@@ -1570,6 +1606,7 @@ static int vpm_start_load(struct t1 *wc)
|
||||
work->wc = wc;
|
||||
|
||||
queue_work(wc->wq, &work->work);
|
||||
wc->not_ready++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1616,12 +1653,23 @@ static void check_and_load_vpm(struct t1 *wc)
|
||||
options.vpmnlptype = vpmnlptype;
|
||||
options.vpmnlpthresh = vpmnlpthresh;
|
||||
options.vpmnlpmaxsupp = vpmnlpmaxsupp;
|
||||
options.channels = (TYPE_T1 == wc->spantype) ? 24 : 32;
|
||||
options.channels = dahdi_is_t1_span(&wc->span) ? 24 : 32;
|
||||
|
||||
/* We do not want to check that the VPM is alive until after we're
|
||||
* done setting it up here, an hour should cover it... */
|
||||
wc->vpm_check = jiffies + HZ*3600;
|
||||
|
||||
/* If there was one already allocated, let's free it. */
|
||||
if (wc->vpmadt032) {
|
||||
vpmadt = wc->vpmadt032;
|
||||
clear_bit(VPM150M_ACTIVE, &vpmadt->control);
|
||||
flush_workqueue(vpmadt->wq);
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
wc->vpmadt032 = NULL;
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
vpmadt032_free(vpmadt);
|
||||
}
|
||||
|
||||
vpmadt = vpmadt032_alloc(&options);
|
||||
if (!vpmadt)
|
||||
return;
|
||||
@@ -1660,6 +1708,8 @@ static void check_and_load_vpm(struct t1 *wc)
|
||||
|
||||
vpmoct_init(vpmoct, t1_vpm_load_complete);
|
||||
}
|
||||
|
||||
set_span_devicetype(wc);
|
||||
}
|
||||
#else
|
||||
static inline void check_and_load_vpm(const struct t1 *wc)
|
||||
@@ -1674,7 +1724,7 @@ static void t1_chan_set_sigcap(struct dahdi_span *span, int x)
|
||||
struct dahdi_chan *chan = wc->chans[x];
|
||||
chan->sigcap = DAHDI_SIG_CLEAR;
|
||||
/* E&M variant supported depends on span type */
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
/* E1 sigcap setup */
|
||||
if (span->lineconfig & DAHDI_CONFIG_CCS) {
|
||||
/* CCS setup */
|
||||
@@ -1757,54 +1807,46 @@ static void t1xxp_disable_hw_preechocan(struct dahdi_chan *chan)
|
||||
vpmoct_preecho_disable(wc->vpmoct, chan->chanpos - 1);
|
||||
}
|
||||
|
||||
static const struct dahdi_span_ops t1_span_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.spanconfig = t1xxp_spanconfig,
|
||||
.chanconfig = t1xxp_chanconfig,
|
||||
.startup = t1xxp_startup,
|
||||
.rbsbits = t1xxp_rbsbits,
|
||||
.maint = t1xxp_maint,
|
||||
.ioctl = t1xxp_ioctl,
|
||||
#ifdef VPM_SUPPORT
|
||||
.enable_hw_preechocan = t1xxp_enable_hw_preechocan,
|
||||
.disable_hw_preechocan = t1xxp_disable_hw_preechocan,
|
||||
.echocan_create = t1xxp_echocan_create,
|
||||
.echocan_name = t1xxp_echocan_name,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int t1_software_init(struct t1 *wc)
|
||||
/**
|
||||
* t1_software_init - Initialize the board for the given type.
|
||||
* @wc: The board to initialize.
|
||||
* @type: The type of board we are, T1 / E1
|
||||
*
|
||||
* This function is called at startup and when the type of the span is changed
|
||||
* via the dahdi_device before the span is assigned a number.
|
||||
*
|
||||
*/
|
||||
static int t1_software_init(struct t1 *wc, enum linemode type)
|
||||
{
|
||||
int x;
|
||||
int num;
|
||||
struct pci_dev *pdev = wc->vb.pdev;
|
||||
struct dahdi_chan *chans[32] = {NULL,};
|
||||
struct dahdi_echocan_state *ec[32] = {NULL,};
|
||||
unsigned long flags;
|
||||
int res = 0;
|
||||
|
||||
/* Find position */
|
||||
for (x = 0; x < ARRAY_SIZE(ifaces); ++x) {
|
||||
if (ifaces[x] == wc) {
|
||||
debug_printk(wc, 1, "software init for card %d\n", x);
|
||||
break;
|
||||
}
|
||||
/* We may already be setup properly. */
|
||||
if (wc->span.channels == ((E1 == type) ? 31 : 24))
|
||||
return 0;
|
||||
|
||||
for (x = 0; x < ((E1 == type) ? 31 : 24); x++) {
|
||||
chans[x] = kzalloc(sizeof(*chans[x]), GFP_KERNEL);
|
||||
ec[x] = kzalloc(sizeof(*ec[x]), GFP_KERNEL);
|
||||
if (!chans[x] || !ec[x])
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
if (x == ARRAY_SIZE(ifaces))
|
||||
return -1;
|
||||
|
||||
t4_serial_setup(wc);
|
||||
|
||||
num = x;
|
||||
sprintf(wc->span.name, "WCT1/%d", num);
|
||||
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d", wc->variety, num);
|
||||
wc->span.manufacturer = "Digium";
|
||||
set_span_devicetype(wc);
|
||||
|
||||
snprintf(wc->span.location, sizeof(wc->span.location) - 1,
|
||||
"PCI Bus %02d Slot %02d", pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn) + 1);
|
||||
/* Because the interrupt handler is running, we need to atomically
|
||||
* swap the channel arrays. */
|
||||
spin_lock_irqsave(&wc->reglock, flags);
|
||||
_t1_free_channels(wc);
|
||||
memcpy(wc->chans, chans, sizeof(wc->chans));
|
||||
memcpy(wc->ec, ec, sizeof(wc->ec));
|
||||
memset(chans, 0, sizeof(chans));
|
||||
memset(ec, 0, sizeof(ec));
|
||||
|
||||
wc->span.irq = pdev->irq;
|
||||
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (type == E1) {
|
||||
wc->span.channels = 31;
|
||||
wc->span.spantype = "E1";
|
||||
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3 |
|
||||
@@ -1817,24 +1859,89 @@ static int t1_software_init(struct t1 *wc)
|
||||
DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
|
||||
wc->span.deflaw = DAHDI_LAW_MULAW;
|
||||
}
|
||||
wc->span.chans = wc->chans;
|
||||
|
||||
spin_unlock_irqrestore(&wc->reglock, flags);
|
||||
|
||||
if (!wc->ddev->location)
|
||||
return -ENOMEM;
|
||||
|
||||
t1_info(wc, "Setting up global serial parameters for %s\n",
|
||||
(dahdi_is_e1_span(&wc->span) ? "E1" : "T1"));
|
||||
|
||||
t4_serial_setup(wc);
|
||||
set_bit(DAHDI_FLAGBIT_RBS, &wc->span.flags);
|
||||
for (x = 0; x < wc->span.channels; x++) {
|
||||
sprintf(wc->chans[x]->name, "WCT1/%d/%d", num, x + 1);
|
||||
sprintf(wc->chans[x]->name, "%s/%d", wc->span.name, x + 1);
|
||||
t1_chan_set_sigcap(&wc->span, x);
|
||||
wc->chans[x]->pvt = wc;
|
||||
wc->chans[x]->chanpos = x + 1;
|
||||
}
|
||||
|
||||
check_and_load_vpm(wc);
|
||||
|
||||
wc->span.ops = &t1_span_ops;
|
||||
if (dahdi_register(&wc->span, 0)) {
|
||||
t1_info(wc, "Unable to register span with DAHDI\n");
|
||||
return -1;
|
||||
}
|
||||
set_span_devicetype(wc);
|
||||
|
||||
return 0;
|
||||
|
||||
error_exit:
|
||||
for (x = 0; x < ARRAY_SIZE(chans); ++x) {
|
||||
kfree(chans[x]);
|
||||
kfree(ec[x]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* t1xx_set_linemode - Change the type of span before assignment.
|
||||
* @span: The span to change.
|
||||
* @linemode: Text string for the line mode.
|
||||
*
|
||||
* This function may be called after the dahdi_device is registered but
|
||||
* before the spans are assigned numbers (and are visible to the rest of
|
||||
* DAHDI).
|
||||
*
|
||||
*/
|
||||
static int t1xxp_set_linemode(struct dahdi_span *span, const char *linemode)
|
||||
{
|
||||
int res;
|
||||
struct t1 *wc = container_of(span, struct t1, span);
|
||||
|
||||
/* We may already be set to the requested type. */
|
||||
if (!strcasecmp(span->spantype, linemode))
|
||||
return 0;
|
||||
|
||||
res = t1_wait_for_ready(wc);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
/* Stop the processing of the channels since we're going to change
|
||||
* them. */
|
||||
clear_bit(INITIALIZED, &wc->bit_flags);
|
||||
smp_mb__after_clear_bit();
|
||||
del_timer_sync(&wc->timer);
|
||||
flush_workqueue(wc->wq);
|
||||
|
||||
if (!strcasecmp(linemode, "t1")) {
|
||||
dev_info(&wc->vb.pdev->dev,
|
||||
"Changing from E1 to T1 line mode.\n");
|
||||
res = t1_software_init(wc, T1);
|
||||
} else if (!strcasecmp(linemode, "e1")) {
|
||||
dev_info(&wc->vb.pdev->dev,
|
||||
"Changing from T1 to E1 line mode.\n");
|
||||
res = t1_software_init(wc, E1);
|
||||
} else {
|
||||
dev_err(&wc->vb.pdev->dev,
|
||||
"'%s' is an unknown linemode.\n", linemode);
|
||||
res = -EINVAL;
|
||||
}
|
||||
|
||||
/* Since we probably reallocated the channels we need to make
|
||||
* sure they are configured before setting INITIALIZED again. */
|
||||
if (!res) {
|
||||
dahdi_init_span(span);
|
||||
set_bit(INITIALIZED, &wc->bit_flags);
|
||||
mod_timer(&wc->timer, jiffies + HZ/5);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -1853,39 +1960,53 @@ static inline unsigned char t1_vpm_out(struct t1 *wc, int unit, const unsigned i
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int t1_hardware_post_init(struct t1 *wc)
|
||||
static int t1_hardware_post_init(struct t1 *wc, enum linemode *type)
|
||||
{
|
||||
int res;
|
||||
unsigned int reg;
|
||||
int reg;
|
||||
int x;
|
||||
|
||||
/* T1 or E1 */
|
||||
if (t1e1override > -1) {
|
||||
if (t1e1override)
|
||||
wc->spantype = TYPE_E1;
|
||||
else
|
||||
wc->spantype = TYPE_T1;
|
||||
if (-1 != t1e1override) {
|
||||
pr_info("t1e1override is deprecated. Please use 'default_linemode'.\n");
|
||||
*type = (t1e1override) ? E1 : T1;
|
||||
} else {
|
||||
u8 pins;
|
||||
res = t1_getpins(wc, &pins);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
wc->spantype = (pins & 0x01) ? TYPE_T1 : TYPE_E1;
|
||||
if (!strcasecmp(default_linemode, "e1")) {
|
||||
*type = E1;
|
||||
} else if (!strcasecmp(default_linemode, "t1")) {
|
||||
*type = T1;
|
||||
} else {
|
||||
u8 pins;
|
||||
res = t1_getpins(wc, &pins);
|
||||
if (res)
|
||||
return res;
|
||||
*type = (pins & 0x01) ? T1 : E1;
|
||||
}
|
||||
}
|
||||
debug_printk(wc, 1, "spantype: %s\n", 1 == wc->spantype ? "T1" : "E1");
|
||||
debug_printk(wc, 1, "linemode: %s\n", (*type == T1) ? "T1" : "E1");
|
||||
|
||||
/* what version of the FALC are we using? */
|
||||
reg = t1_setreg(wc, 0x4a, 0xaa);
|
||||
reg = t1_getreg(wc, 0x4a);
|
||||
if (reg < 0) {
|
||||
t1_info(wc, "Failed to read FALC version (%d)\n", reg);
|
||||
return -EIO;
|
||||
}
|
||||
debug_printk(wc, 1, "FALC version: %08x\n", reg);
|
||||
|
||||
/* make sure reads and writes work */
|
||||
for (x = 0; x < 256; x++) {
|
||||
t1_setreg(wc, 0x14, x);
|
||||
reg = t1_getreg(wc, 0x14);
|
||||
if (reg != x)
|
||||
t1_info(wc, "Wrote '%x' but read '%x'\n", x, reg);
|
||||
if (reg < 0) {
|
||||
t1_info(wc, "Failed register read (%d)\n", reg);
|
||||
return -EIO;
|
||||
}
|
||||
if (reg != x) {
|
||||
t1_info(wc, "Register test failed. "
|
||||
"Wrote '%x' but read '%x'\n", x, reg);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
t1_setleds(wc, wc->ledstate);
|
||||
@@ -1913,7 +2034,7 @@ static inline void t1_check_alarms(struct t1 *wc)
|
||||
/* And consider only carrier alarms */
|
||||
wc->span.alarms &= (DAHDI_ALARM_RED | DAHDI_ALARM_BLUE | DAHDI_ALARM_NOTOPEN);
|
||||
|
||||
if (wc->spantype == TYPE_E1) {
|
||||
if (dahdi_is_e1_span(&wc->span)) {
|
||||
if (c & 0x04) {
|
||||
/* No multiframe found, force RAI high after 400ms only if
|
||||
we haven't found a multiframe since last loss
|
||||
@@ -2239,7 +2360,7 @@ static inline void t1_receiveprep(struct t1 *wc, const u8* sframe)
|
||||
wc->rxident = eframe[EFRAME_SIZE + 1];
|
||||
wc->statreg = eframe[EFRAME_SIZE + 2];
|
||||
if (wc->rxident != expected) {
|
||||
wc->span.irqmisses++;
|
||||
wc->ddev->irqmisses++;
|
||||
_resend_cmds(wc);
|
||||
if (unlikely(debug)) {
|
||||
t1_info(wc, "oops: rxident=%d "
|
||||
@@ -2522,14 +2643,31 @@ static inline void remove_sysfs_files(struct t1 *wc) { return; }
|
||||
|
||||
#endif /* CONFIG_VOICEBUS_SYSFS */
|
||||
|
||||
static const struct dahdi_span_ops t1_span_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.spanconfig = t1xxp_spanconfig,
|
||||
.chanconfig = t1xxp_chanconfig,
|
||||
.startup = t1xxp_startup,
|
||||
.rbsbits = t1xxp_rbsbits,
|
||||
.maint = t1xxp_maint,
|
||||
.ioctl = t1xxp_ioctl,
|
||||
.set_spantype = t1xxp_set_linemode,
|
||||
#ifdef VPM_SUPPORT
|
||||
.enable_hw_preechocan = t1xxp_enable_hw_preechocan,
|
||||
.disable_hw_preechocan = t1xxp_disable_hw_preechocan,
|
||||
.echocan_create = t1xxp_echocan_create,
|
||||
.echocan_name = t1xxp_echocan_name,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct t1 *wc;
|
||||
struct t1_desc *d = (struct t1_desc *) ent->driver_data;
|
||||
const struct t1_desc *d = (struct t1_desc *) ent->driver_data;
|
||||
unsigned int x;
|
||||
int res;
|
||||
unsigned int index = -1;
|
||||
enum linemode type;
|
||||
|
||||
for (x = 0; x < ARRAY_SIZE(ifaces); x++) {
|
||||
if (!ifaces[x]) {
|
||||
@@ -2548,18 +2686,22 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
if (!wc)
|
||||
return -ENOMEM;
|
||||
|
||||
wc->not_ready = 1;
|
||||
/* Set the performance counters to -1 since this card currently does
|
||||
* not support collecting them. */
|
||||
memset(&wc->span.count, -1, sizeof(wc->span.count));
|
||||
|
||||
ifaces[index] = wc;
|
||||
|
||||
sprintf(wc->span.name, "WCT1/%d", index);
|
||||
snprintf(wc->span.desc, sizeof(wc->span.desc) - 1, "%s Card %d",
|
||||
d->name, index);
|
||||
wc->not_ready = 1;
|
||||
wc->ledstate = -1;
|
||||
wc->variety = d->name;
|
||||
wc->txident = 1;
|
||||
spin_lock_init(&wc->reglock);
|
||||
INIT_LIST_HEAD(&wc->active_cmds);
|
||||
INIT_LIST_HEAD(&wc->pending_cmds);
|
||||
|
||||
wc->variety = d->name;
|
||||
wc->txident = 1;
|
||||
|
||||
# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
wc->timer.function = te12xp_timer;
|
||||
wc->timer.data = (unsigned long)wc;
|
||||
@@ -2580,6 +2722,22 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
INIT_WORK(&wc->vpm_check_work, vpm_check_func);
|
||||
# endif
|
||||
|
||||
wc->ddev = dahdi_create_device();
|
||||
if (!wc->ddev) {
|
||||
ifaces[index] = NULL;
|
||||
kfree(wc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
wc->ddev->manufacturer = "Digium";
|
||||
wc->ddev->location = kasprintf(GFP_KERNEL, "PCI Bus %02d Slot %02d",
|
||||
pdev->bus->number,
|
||||
PCI_SLOT(pdev->devfn) + 1);
|
||||
if (!wc->ddev->location) {
|
||||
ifaces[index] = NULL;
|
||||
kfree(wc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VOICEBUS_ECREFERENCE
|
||||
for (x = 0; x < ARRAY_SIZE(wc->ec_reference); ++x) {
|
||||
/* 256 is used here since it is the largest power of two that
|
||||
@@ -2596,6 +2754,13 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
}
|
||||
#endif /* CONFIG_VOICEBUS_ECREFERENCE */
|
||||
|
||||
#ifdef CONFIG_VOICEBUS_DISABLE_ASPM
|
||||
if (is_pcie(wc)) {
|
||||
pci_disable_link_state(pdev->bus->self, PCIE_LINK_STATE_L0S |
|
||||
PCIE_LINK_STATE_L1 | PCIE_LINK_STATE_CLKPM);
|
||||
};
|
||||
#endif
|
||||
|
||||
snprintf(wc->name, sizeof(wc->name)-1, "wcte12xp%d", index);
|
||||
pci_set_drvdata(pdev, wc);
|
||||
wc->vb.ops = &voicebus_operations;
|
||||
@@ -2611,6 +2776,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
wc->wq = create_singlethread_workqueue(wc->name);
|
||||
if (!wc->wq) {
|
||||
kfree(wc);
|
||||
ifaces[index] = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@@ -2624,36 +2790,33 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
if (voicebus_start(&wc->vb)) {
|
||||
voicebus_release(&wc->vb);
|
||||
free_wc(wc);
|
||||
ifaces[index] = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
res = t1_hardware_post_init(wc);
|
||||
res = t1_hardware_post_init(wc, &type);
|
||||
if (res) {
|
||||
voicebus_release(&wc->vb);
|
||||
free_wc(wc);
|
||||
ifaces[index] = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
for (x = 0; x < (wc->spantype == TYPE_E1 ? 31 : 24); x++) {
|
||||
wc->chans[x] = kzalloc(sizeof(*wc->chans[x]), GFP_KERNEL);
|
||||
if (!wc->chans[x]) {
|
||||
free_wc(wc);
|
||||
ifaces[index] = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
wc->span.chans = wc->chans;
|
||||
|
||||
wc->ec[x] = kzalloc(sizeof(*wc->ec[x]), GFP_KERNEL);
|
||||
if (!wc->ec[x]) {
|
||||
free_wc(wc);
|
||||
ifaces[index] = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
res = t1_software_init(wc);
|
||||
res = t1_software_init(wc, type);
|
||||
if (res) {
|
||||
voicebus_release(&wc->vb);
|
||||
free_wc(wc);
|
||||
ifaces[index] = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
wc->span.ops = &t1_span_ops;
|
||||
list_add_tail(&wc->span.device_node, &wc->ddev->spans);
|
||||
res = dahdi_register_device(wc->ddev, &wc->vb.pdev->dev);
|
||||
if (res) {
|
||||
t1_info(wc, "Unable to register with DAHDI\n");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -2663,10 +2826,7 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
|
||||
t1_info(wc, "Found a %s\n", wc->variety);
|
||||
voicebus_unlock_latency(&wc->vb);
|
||||
|
||||
/* If there is VPMADT032 module attached to this device, it will
|
||||
* signal ready after the channels are configured and ready for use. */
|
||||
if (!wc->vpmadt032)
|
||||
wc->not_ready--;
|
||||
wc->not_ready--;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2681,7 +2841,7 @@ static void __devexit te12xp_remove_one(struct pci_dev *pdev)
|
||||
if (!wc)
|
||||
return;
|
||||
|
||||
dahdi_unregister(&wc->span);
|
||||
dahdi_unregister_device(wc->ddev);
|
||||
|
||||
remove_sysfs_files(wc);
|
||||
|
||||
@@ -2772,6 +2932,16 @@ static int __init te12xp_init(void)
|
||||
if (!cmd_cache)
|
||||
return -ENOMEM;
|
||||
|
||||
if (-1 != t1e1override) {
|
||||
pr_info("'t1e1override' is deprecated. "
|
||||
"Please use 'default_linemode' instead\n");
|
||||
} else if (strcasecmp(default_linemode, "auto") &&
|
||||
strcasecmp(default_linemode, "t1") &&
|
||||
strcasecmp(default_linemode, "e1")) {
|
||||
pr_err("'%s' is an unknown span type.", default_linemode);
|
||||
default_linemode = "auto";
|
||||
return -EINVAL;
|
||||
}
|
||||
res = dahdi_pci_module(&te12xp_driver);
|
||||
if (res) {
|
||||
kmem_cache_destroy(cmd_cache);
|
||||
@@ -2790,6 +2960,9 @@ static void __exit te12xp_cleanup(void)
|
||||
|
||||
module_param(debug, int, S_IRUGO | S_IWUSR);
|
||||
module_param(t1e1override, int, S_IRUGO | S_IWUSR);
|
||||
module_param(default_linemode, charp, S_IRUGO);
|
||||
MODULE_PARM_DESC(default_linemode, "\"auto\"(default), \"e1\", or \"t1\". "
|
||||
"\"auto\" will use the value from the hardware jumpers.");
|
||||
module_param(j1mode, int, S_IRUGO | S_IWUSR);
|
||||
module_param(alarmdebounce, int, S_IRUGO | S_IWUSR);
|
||||
module_param(losalarmdebounce, int, S_IRUGO | S_IWUSR);
|
||||
|
||||
@@ -74,8 +74,10 @@
|
||||
#define CMD_BYTE(slot, a, is_vpm) (slot*6)+(a*2)+is_vpm /* only even slots */
|
||||
//TODO: make a separate macro
|
||||
|
||||
#define TYPE_T1 1
|
||||
#define TYPE_E1 2
|
||||
enum linemode {
|
||||
T1 = 1,
|
||||
E1,
|
||||
};
|
||||
|
||||
struct command {
|
||||
struct list_head node;
|
||||
@@ -94,7 +96,6 @@ 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;
|
||||
@@ -116,6 +117,7 @@ struct t1 {
|
||||
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 */
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
|
||||
static const char rcsid[] = "$Id$";
|
||||
|
||||
#ifndef DAHDI_SIG_HARDHDLC
|
||||
#error Cannot build BRI without HARDHDLC supprt
|
||||
#endif
|
||||
|
||||
static DEF_PARM(int, debug, 0, 0644, "Print DBG statements"); /* must be before dahdi_debug.h */
|
||||
static DEF_PARM(uint, poll_interval, 500, 0644, "Poll channel state interval in milliseconds (0 - disable)");
|
||||
static DEF_PARM_BOOL(nt_keepalive, 1, 0644, "Force BRI_NT to keep trying connection");
|
||||
@@ -129,22 +133,7 @@ typedef union {
|
||||
#define REG30_LOST 3 /* in polls */
|
||||
#define DCHAN_LOST 15000 /* in ticks */
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
#define BRI_DCHAN_SIGCAP ( \
|
||||
DAHDI_SIG_EM | \
|
||||
DAHDI_SIG_CLEAR | \
|
||||
DAHDI_SIG_FXSLS | \
|
||||
DAHDI_SIG_FXSGS | \
|
||||
DAHDI_SIG_FXSKS | \
|
||||
DAHDI_SIG_FXOLS | \
|
||||
DAHDI_SIG_FXOGS | \
|
||||
DAHDI_SIG_FXOKS | \
|
||||
DAHDI_SIG_CAS | \
|
||||
DAHDI_SIG_SF \
|
||||
)
|
||||
#else
|
||||
#define BRI_DCHAN_SIGCAP DAHDI_SIG_HARDHDLC
|
||||
#endif
|
||||
#define BRI_BCHAN_SIGCAP (DAHDI_SIG_CLEAR | DAHDI_SIG_DACS)
|
||||
|
||||
#define IS_NT(xpd) (PHONEDEV(xpd).direction == TO_PHONE)
|
||||
@@ -218,13 +207,7 @@ struct BRI_priv_data {
|
||||
/*
|
||||
* D-Chan: buffers + extra state info.
|
||||
*/
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
int dchan_r_idx;
|
||||
byte dchan_rbuf[DCHAN_BUFSIZE];
|
||||
#else
|
||||
atomic_t hdlc_pending;
|
||||
#endif
|
||||
byte dchan_tbuf[DCHAN_BUFSIZE];
|
||||
bool txframe_begin;
|
||||
|
||||
uint tick_counter;
|
||||
@@ -438,22 +421,6 @@ static void nt_activation(xpd_t *xpd, bool on)
|
||||
/*
|
||||
* D-Chan receive
|
||||
*/
|
||||
static void bri_hdlc_abort(xpd_t *xpd, struct dahdi_chan *dchan, int event)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(debug & DBG_COMMANDS)
|
||||
dump_hex_buf(xpd, "D-Chan(abort) RX: dchan_rbuf",
|
||||
priv->dchan_rbuf, priv->dchan_r_idx);
|
||||
priv->dchan_r_idx = 0;
|
||||
#else
|
||||
dahdi_hdlc_abort(dchan, event);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int len)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
@@ -461,21 +428,11 @@ static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int l
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(priv->dchan_r_idx < 4) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX short frame (dchan_r_idx=%d)\n",
|
||||
priv->dchan_r_idx);
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
|
||||
bri_hdlc_abort(xpd, dchan, DAHDI_EVENT_ABORT);
|
||||
return -EPROTO;
|
||||
}
|
||||
#else
|
||||
if(len <= 0) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX DROP: short frame (len=%d)\n", len);
|
||||
bri_hdlc_abort(xpd, dchan, DAHDI_EVENT_ABORT);
|
||||
dahdi_hdlc_abort(dchan, DAHDI_EVENT_ABORT);
|
||||
return -EPROTO;
|
||||
}
|
||||
#endif
|
||||
status = buf[len-1];
|
||||
if(status) {
|
||||
int event = DAHDI_EVENT_ABORT;
|
||||
@@ -487,132 +444,12 @@ static int bri_check_stat(xpd_t *xpd, struct dahdi_chan *dchan, byte *buf, int l
|
||||
event = DAHDI_EVENT_BADFCS;
|
||||
}
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", buf, len);
|
||||
bri_hdlc_abort(xpd, dchan, event);
|
||||
dahdi_hdlc_abort(dchan, event);
|
||||
return -EPROTO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bri_hdlc_putbuf(xpd_t *xpd, struct dahdi_chan *dchan,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
struct BRI_priv_data *priv;
|
||||
byte *dchan_buf;
|
||||
byte *dst;
|
||||
int idx;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
dchan_buf = dchan->readchunk;
|
||||
idx = priv->dchan_r_idx;
|
||||
if(idx + len >= DCHAN_BUFSIZE) {
|
||||
XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
|
||||
dump_hex_buf(xpd, " current packet", buf, len);
|
||||
dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
|
||||
return -ENOSPC;
|
||||
}
|
||||
dst = dchan_buf + idx;
|
||||
idx += len;
|
||||
priv->dchan_r_idx = idx;
|
||||
memcpy(dst, buf, len);
|
||||
#else
|
||||
dahdi_hdlc_putbuf(dchan, buf, len);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bri_hdlc_finish(xpd_t *xpd, struct dahdi_chan *dchan)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
dchan->bytes2receive = priv->dchan_r_idx - 1;
|
||||
dchan->eofrx = 1;
|
||||
#else
|
||||
dahdi_hdlc_finish(dchan);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
byte *src;
|
||||
byte *dst;
|
||||
byte *dchan_buf;
|
||||
struct dahdi_chan *dchan;
|
||||
uint len;
|
||||
bool eoframe;
|
||||
int idx;
|
||||
int ret = 0;
|
||||
|
||||
src = REG_XDATA(regcmd);
|
||||
len = regcmd->bytes;
|
||||
eoframe = regcmd->eoframe;
|
||||
if(len <= 0)
|
||||
return 0;
|
||||
if(!SPAN_REGISTERED(xpd)) /* Nowhere to copy data */
|
||||
return 0;
|
||||
BUG_ON(!xpd);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
xbus = xpd->xbus;
|
||||
dchan = XPD_CHAN(xpd, 2);
|
||||
if(!IS_OFFHOOK(xpd, 2)) { /* D-chan is used? */
|
||||
static int rate_limit;
|
||||
|
||||
if((rate_limit++ % 1000) == 0)
|
||||
XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->bytes2transmit = 0;
|
||||
goto out;
|
||||
}
|
||||
dchan_buf = dchan->readchunk;
|
||||
idx = priv->dchan_r_idx;
|
||||
if(idx + len >= DCHAN_BUFSIZE) {
|
||||
XPD_ERR(xpd, "D-Chan RX overflow: %d\n", idx);
|
||||
dump_hex_buf(xpd, " current packet", src, len);
|
||||
dump_hex_buf(xpd, " dchan_buf", dchan_buf, idx);
|
||||
ret = -ENOSPC;
|
||||
if(eoframe)
|
||||
goto drop;
|
||||
goto out;
|
||||
}
|
||||
dst = dchan_buf + idx;
|
||||
idx += len;
|
||||
priv->dchan_r_idx = idx;
|
||||
memcpy(dst, src, len);
|
||||
if(!eoframe)
|
||||
goto out;
|
||||
if(idx < 4) {
|
||||
XPD_NOTICE(xpd, "D-Chan RX short frame (idx=%d)\n", idx);
|
||||
dump_hex_buf(xpd, "D-Chan RX: current packet", src, len);
|
||||
dump_hex_buf(xpd, "D-Chan RX: chan_buf", dchan_buf, idx);
|
||||
ret = -EPROTO;
|
||||
goto drop;
|
||||
}
|
||||
if((ret = bri_check_stat(xpd, dchan, dchan_buf, idx)) < 0)
|
||||
goto drop;
|
||||
if(debug)
|
||||
dump_dchan_packet(xpd, 0, dchan_buf, idx /* - 3 */); /* Print checksum? */
|
||||
/*
|
||||
* Tell Dahdi that we received idx-1 bytes. They include the data and a 2-byte checksum.
|
||||
* The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
|
||||
* we would drop the packet in the "if(dchan_buf[idx-1])" above.
|
||||
*/
|
||||
dchan->bytes2receive = idx - 1;
|
||||
dchan->eofrx = 1;
|
||||
priv->dchan_rx_counter++;
|
||||
priv->dchan_norx_ticks = 0;
|
||||
drop:
|
||||
priv->dchan_r_idx = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
@@ -638,16 +475,10 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
|
||||
if((rate_limit++ % 1000) == 0)
|
||||
XPD_DBG(SIGNAL, xpd, "D-Chan unused\n");
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->bytes2transmit = 0;
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
XPD_DBG(GENERAL, xpd, "D-Chan RX: eoframe=%d len=%d\n", eoframe, len);
|
||||
ret = bri_hdlc_putbuf(xpd, dchan, src, (eoframe) ? len - 1 : len);
|
||||
if(ret < 0)
|
||||
goto out;
|
||||
dahdi_hdlc_putbuf(dchan, src, (eoframe) ? len - 1 : len);
|
||||
if(!eoframe)
|
||||
goto out;
|
||||
if((ret = bri_check_stat(xpd, dchan, src, len)) < 0)
|
||||
@@ -657,18 +488,16 @@ static int rx_dchan(xpd_t *xpd, reg_cmd_t *regcmd)
|
||||
* The last byte (that we don't pass on) is 0 if the checksum is correct. If it were wrong,
|
||||
* we would drop the packet in the "if(src[len-1])" above.
|
||||
*/
|
||||
bri_hdlc_finish(xpd, dchan);
|
||||
dahdi_hdlc_finish(dchan);
|
||||
priv->dchan_rx_counter++;
|
||||
priv->dchan_norx_ticks = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* D-Chan transmit
|
||||
*/
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
/* DAHDI calls this when it has data it wants to send to the HDLC controller */
|
||||
static void bri_hdlc_hard_xmit(struct dahdi_chan *chan)
|
||||
{
|
||||
@@ -683,86 +512,129 @@ static void bri_hdlc_hard_xmit(struct dahdi_chan *chan)
|
||||
atomic_inc(&priv->hdlc_pending);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int bri_hdlc_getbuf(struct dahdi_chan *dchan, unsigned char *buf,
|
||||
unsigned int *size)
|
||||
static int send_dchan_frame(xpd_t *xpd, xframe_t *xframe, bool is_eof)
|
||||
{
|
||||
int len = *size;
|
||||
int eoframe;
|
||||
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
len = dchan->bytes2transmit; /* dchan's hdlc package len */
|
||||
if(len > *size)
|
||||
len = *size; /* Silent truncation */
|
||||
eoframe = dchan->eoftx; /* dchan's end of frame */
|
||||
dchan->bytes2transmit = 0;
|
||||
dchan->eoftx = 0;
|
||||
dchan->bytes2receive = 0;
|
||||
dchan->eofrx = 0;
|
||||
#else
|
||||
eoframe = dahdi_hdlc_getbuf(dchan, buf, &len);
|
||||
#endif
|
||||
*size = len;
|
||||
return eoframe;
|
||||
}
|
||||
|
||||
static int tx_dchan(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
struct dahdi_chan *dchan;
|
||||
int len;
|
||||
int eoframe;
|
||||
int ret;
|
||||
struct BRI_priv_data *priv;
|
||||
int ret;
|
||||
|
||||
XPD_DBG(COMMANDS, xpd, "eoframe=%d\n", is_eof);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
if(atomic_read(&priv->hdlc_pending) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
if(!SPAN_REGISTERED(xpd) || !(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING))
|
||||
return 0;
|
||||
dchan = XPD_CHAN(xpd, 2);
|
||||
len = ARRAY_SIZE(priv->dchan_tbuf);
|
||||
if(len > MULTIBYTE_MAX_LEN)
|
||||
len = MULTIBYTE_MAX_LEN;
|
||||
eoframe = bri_hdlc_getbuf(dchan, priv->dchan_tbuf, &len);
|
||||
if(len <= 0)
|
||||
return 0; /* Nothing to transmit on D channel */
|
||||
if(len > MULTIBYTE_MAX_LEN) {
|
||||
XPD_ERR(xpd, "%s: len=%d. need to split. Unimplemented.\n", __FUNCTION__, len);
|
||||
dump_hex_buf(xpd, "D-Chan TX:", priv->dchan_tbuf, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
if(!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags) && !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
|
||||
if (!test_bit(HFC_L1_ACTIVATED, &priv->l1_flags)
|
||||
&& !test_bit(HFC_L1_ACTIVATING, &priv->l1_flags)) {
|
||||
XPD_DBG(SIGNAL, xpd, "Want to transmit: Kick D-Channel transmiter\n");
|
||||
if(! IS_NT(xpd))
|
||||
if (!IS_NT(xpd))
|
||||
te_activation(xpd, 1);
|
||||
else
|
||||
nt_activation(xpd, 1);
|
||||
}
|
||||
if(debug)
|
||||
dump_dchan_packet(xpd, 1, priv->dchan_tbuf, len);
|
||||
if(eoframe)
|
||||
priv->txframe_begin = 1;
|
||||
else
|
||||
priv->txframe_begin = 0;
|
||||
XPD_DBG(COMMANDS, xpd, "eoframe=%d len=%d\n", eoframe, len);
|
||||
ret = send_multibyte_request(xpd->xbus, xpd->addr.unit, xpd->addr.subunit,
|
||||
eoframe, priv->dchan_tbuf, len);
|
||||
if(ret < 0)
|
||||
XPD_NOTICE(xpd, "%s: failed sending xframe\n", __FUNCTION__);
|
||||
if(eoframe) {
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
dump_xframe("send_dchan_frame", xpd->xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xpd->xbus, xframe);
|
||||
if (ret < 0)
|
||||
XPD_ERR(xpd, "%s: failed sending xframe\n", __func__);
|
||||
if (is_eof) {
|
||||
atomic_dec(&priv->hdlc_pending);
|
||||
#endif
|
||||
priv->dchan_tx_counter++;
|
||||
}
|
||||
priv->txframe_begin = 1;
|
||||
} else
|
||||
priv->txframe_begin = 0;
|
||||
priv->dchan_notx_ticks = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill a single multibyte REGISTER_REQUEST
|
||||
*/
|
||||
static void fill_multibyte(xpd_t *xpd, xpacket_t *pack, bool eoframe,
|
||||
char *buf, int len)
|
||||
{
|
||||
reg_cmd_t *reg_cmd;
|
||||
char *p;
|
||||
|
||||
XPACKET_INIT(pack, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx, 0, 0);
|
||||
XPACKET_LEN(pack) = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = len;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = xpd->addr.subunit;
|
||||
reg_cmd->eoframe = eoframe;
|
||||
p = REG_XDATA(reg_cmd);
|
||||
memcpy(p, buf, len);
|
||||
if (debug)
|
||||
dump_dchan_packet(xpd, 1, p, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Transmit available D-Channel frames
|
||||
*
|
||||
* - FPGA firmware expect to get this as a sequence of REGISTER_REQUEST
|
||||
* multibyte commands.
|
||||
* - The payload of each command is limited to MULTIBYTE_MAX_LEN bytes.
|
||||
* - We batch several REGISTER_REQUEST packets into a single xframe.
|
||||
* - The xframe is terminated when we get a bri "end of frame"
|
||||
* or when the xframe is full (should not happen).
|
||||
*/
|
||||
static int tx_dchan(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
int packet_count;
|
||||
int eoframe;
|
||||
int ret;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
if (atomic_read(&priv->hdlc_pending) == 0)
|
||||
return 0;
|
||||
if (!SPAN_REGISTERED(xpd) ||
|
||||
!(PHONEDEV(xpd).span.flags & DAHDI_FLAG_RUNNING))
|
||||
return 0;
|
||||
/* Allocate frame */
|
||||
xframe = ALLOC_SEND_XFRAME(xpd->xbus);
|
||||
if (!xframe) {
|
||||
XPD_NOTICE(xpd, "%s: failed to allocate new xframe\n",
|
||||
__func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
for (packet_count = 0, eoframe = 0; !eoframe; packet_count++) {
|
||||
int packet_len = RPACKET_SIZE(GLOBAL, REGISTER_REQUEST);
|
||||
char buf[MULTIBYTE_MAX_LEN];
|
||||
int len = MULTIBYTE_MAX_LEN;
|
||||
|
||||
/* Reserve packet */
|
||||
pack = xframe_next_packet(xframe, packet_len);
|
||||
if (!pack) {
|
||||
BUG_ON(!packet_count);
|
||||
/*
|
||||
* A split. Send what we currently have.
|
||||
*/
|
||||
XPD_NOTICE(xpd,
|
||||
"%s: xframe is full (%d packets)\n",
|
||||
__func__, packet_count);
|
||||
break;
|
||||
}
|
||||
/* Get data from DAHDI */
|
||||
eoframe = dahdi_hdlc_getbuf(XPD_CHAN(xpd, 2), buf, &len);
|
||||
if (len <= 0) {
|
||||
/*
|
||||
* Already checked priv->hdlc_pending,
|
||||
* should never get here.
|
||||
*/
|
||||
if (printk_ratelimit())
|
||||
XPD_ERR(xpd,
|
||||
"%s: hdlc_pending, but nothing to transmit?\n",
|
||||
__func__);
|
||||
FREE_SEND_XFRAME(xpd->xbus, xframe);
|
||||
return -EINVAL;
|
||||
}
|
||||
BUG_ON(len > MULTIBYTE_MAX_LEN);
|
||||
fill_multibyte(xpd, pack, eoframe != 0, buf, len);
|
||||
}
|
||||
return send_dchan_frame(xpd, xframe, eoframe != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*---------------- BRI: Methods -------------------------------------------*/
|
||||
|
||||
static void bri_proc_remove(xbus_t *xbus, xpd_t *xpd)
|
||||
@@ -853,9 +725,7 @@ static const struct dahdi_span_ops BRI_span_ops = {
|
||||
.chanconfig = bri_chanconfig,
|
||||
.startup = bri_startup,
|
||||
.shutdown = bri_shutdown,
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
.hdlc_hard_xmit = bri_hdlc_hard_xmit,
|
||||
#endif
|
||||
.open = xpp_open,
|
||||
.close = xpp_close,
|
||||
.hooksig = xpp_hooksig, /* Only with RBS bits */
|
||||
@@ -863,6 +733,7 @@ static const struct dahdi_span_ops BRI_span_ops = {
|
||||
.maint = xpp_maint,
|
||||
.echocan_create = xpp_echocan_create,
|
||||
.echocan_name = xpp_echocan_name,
|
||||
.assigned = xpp_span_assigned,
|
||||
#ifdef DAHDI_SYNC_TICK
|
||||
.sync_tick = dahdi_sync_tick,
|
||||
#endif
|
||||
@@ -903,19 +774,7 @@ static int BRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
cur_chan->sigcap = BRI_DCHAN_SIGCAP;
|
||||
clear_bit(DAHDI_FLAGBIT_HDLC, &cur_chan->flags);
|
||||
priv->txframe_begin = 1;
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
priv->dchan_r_idx = 0;
|
||||
set_bit(DAHDI_FLAGBIT_BRIDCHAN, &cur_chan->flags);
|
||||
/* Setup big buffers for D-Channel rx/tx */
|
||||
cur_chan->readchunk = priv->dchan_rbuf;
|
||||
cur_chan->writechunk = priv->dchan_tbuf;
|
||||
|
||||
cur_chan->maxbytes2transmit = MULTIBYTE_MAX_LEN;
|
||||
cur_chan->bytes2transmit = 0;
|
||||
cur_chan->bytes2receive = 0;
|
||||
#else
|
||||
atomic_set(&priv->hdlc_pending, 0);
|
||||
#endif
|
||||
} else {
|
||||
cur_chan->sigcap = BRI_BCHAN_SIGCAP;
|
||||
}
|
||||
@@ -1145,15 +1004,6 @@ static int BRI_card_open(xpd_t *xpd, lineno_t pos)
|
||||
static int BRI_card_close(xpd_t *xpd, lineno_t pos)
|
||||
{
|
||||
/* Clear D-Channel pending data */
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
struct dahdi_chan *chan = XPD_CHAN(xpd, pos);
|
||||
|
||||
/* Clear D-Channel pending data */
|
||||
chan->bytes2receive = 0;
|
||||
chan->eofrx = 0;
|
||||
chan->bytes2transmit = 0;
|
||||
chan->eoftx = 0;
|
||||
#endif
|
||||
if(pos == 2) {
|
||||
LINE_DBG(SIGNAL, xpd, pos, "ONHOOK the whole span\n");
|
||||
BIT_CLR(PHONEDEV(xpd).offhook_state, 0);
|
||||
@@ -1201,6 +1051,8 @@ static int bri_spanconfig(struct file *file, struct dahdi_span *span,
|
||||
framingstr, codingstr, crcstr,
|
||||
lc->lineconfig,
|
||||
lc->sync);
|
||||
PHONEDEV(xpd).timing_priority = lc->sync;
|
||||
elect_syncer("BRI-spanconfig");
|
||||
/*
|
||||
* FIXME: validate
|
||||
*/
|
||||
@@ -1252,9 +1104,6 @@ static int bri_startup(struct file *file, struct dahdi_span *span)
|
||||
*
|
||||
* Don't Get Mad, Get Even: Now we override dahdi :-)
|
||||
*/
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
set_bit(DAHDI_FLAGBIT_BRIDCHAN, &dchan->flags);
|
||||
#endif
|
||||
clear_bit(DAHDI_FLAGBIT_HDLC, &dchan->flags);
|
||||
}
|
||||
return 0;
|
||||
@@ -1428,6 +1277,18 @@ static void BRI_card_pcm_tospan(xpd_t *xpd, xpacket_t *pack)
|
||||
}
|
||||
}
|
||||
|
||||
static int BRI_timing_priority(xpd_t *xpd)
|
||||
{
|
||||
struct BRI_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
if (priv->layer1_up)
|
||||
return PHONEDEV(xpd).timing_priority;
|
||||
XPD_DBG(SYNC, xpd, "No timing priority (no layer1)\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int BRI_echocancel_timeslot(xpd_t *xpd, int pos)
|
||||
{
|
||||
return xpd->addr.subunit * 4 + pos;
|
||||
@@ -1695,7 +1556,7 @@ static const struct phoneops bri_phoneops = {
|
||||
.card_pcm_recompute = BRI_card_pcm_recompute,
|
||||
.card_pcm_fromspan = BRI_card_pcm_fromspan,
|
||||
.card_pcm_tospan = BRI_card_pcm_tospan,
|
||||
.card_timing_priority = generic_timing_priority,
|
||||
.card_timing_priority = BRI_timing_priority,
|
||||
.echocancel_timeslot = BRI_echocancel_timeslot,
|
||||
.echocancel_setmask = BRI_echocancel_setmask,
|
||||
.card_ioctl = BRI_card_ioctl,
|
||||
@@ -1775,9 +1636,6 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
|
||||
} else {
|
||||
len += sprintf(page + len, "(dead)\n");
|
||||
}
|
||||
#ifndef CONFIG_DAHDI_BRI_DCHANS
|
||||
len += sprintf(page + len, "hdlc_pending=%d\n", atomic_read(&priv->hdlc_pending));
|
||||
#endif
|
||||
len += sprintf(page + len, "dchan_notx_ticks: %d\n", priv->dchan_notx_ticks);
|
||||
len += sprintf(page + len, "dchan_norx_ticks: %d\n", priv->dchan_norx_ticks);
|
||||
len += sprintf(page + len, "LED: %-10s = %d\n", "GREEN", priv->ledstate[GREEN_LED]);
|
||||
@@ -1797,22 +1655,6 @@ static int proc_bri_info_read(char *page, char **start, off_t off, int count, in
|
||||
}
|
||||
#endif
|
||||
|
||||
static DRIVER_ATTR_READER(dchan_hardhdlc_show, drv,buf)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
#if defined(CONFIG_DAHDI_BRI_DCHANS)
|
||||
len += sprintf(buf + len, "0\n");
|
||||
#elif defined(DAHDI_SIG_HARDHDLC)
|
||||
len += sprintf(buf + len, "1\n");
|
||||
#else
|
||||
#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
|
||||
#endif
|
||||
return len;
|
||||
}
|
||||
|
||||
static DRIVER_ATTR(dchan_hardhdlc,S_IRUGO,dchan_hardhdlc_show,NULL);
|
||||
|
||||
static int bri_xpd_probe(struct device *dev)
|
||||
{
|
||||
xpd_t *xpd;
|
||||
@@ -1855,18 +1697,7 @@ static int __init card_bri_startup(void)
|
||||
|
||||
if((ret = xpd_driver_register(&bri_driver.driver)) < 0)
|
||||
return ret;
|
||||
ret = driver_create_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
INFO("revision %s\n", XPP_VERSION);
|
||||
#if defined(CONFIG_DAHDI_BRI_DCHANS)
|
||||
INFO("FEATURE: WITH BRISTUFF\n");
|
||||
#elif defined(DAHDI_SIG_HARDHDLC)
|
||||
INFO("FEATURE: WITH HARDHDLC\n");
|
||||
#else
|
||||
#error Cannot build BRI without BRISTUFF or HARDHDLC supprt
|
||||
#endif
|
||||
|
||||
xproto_register(&PROTO_TABLE(BRI));
|
||||
return 0;
|
||||
}
|
||||
@@ -1875,7 +1706,6 @@ static void __exit card_bri_cleanup(void)
|
||||
{
|
||||
DBG(GENERAL, "\n");
|
||||
xproto_unregister(&PROTO_TABLE(BRI));
|
||||
driver_remove_file(&bri_driver.driver, &driver_attr_dchan_hardhdlc);
|
||||
xpd_driver_unregister(&bri_driver.driver);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ enum fxo_opcodes {
|
||||
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 */
|
||||
};
|
||||
|
||||
@@ -42,6 +42,8 @@ static DEF_PARM(uint, poll_digital_inputs, 1000, 0644, "Poll Digital Inputs");
|
||||
|
||||
static DEF_PARM_BOOL(vmwi_ioctl, 1, 0644, "Asterisk support VMWI notification via ioctl");
|
||||
static DEF_PARM_BOOL(ring_trapez, 0, 0664, "Use trapezoid ring type");
|
||||
static DEF_PARM_BOOL(lower_ringing_noise, 0, 0664,
|
||||
"Lower ringing noise (may loose CallerID)");
|
||||
|
||||
/* Signaling is opposite (fxo signalling for fxs card) */
|
||||
#if 1
|
||||
@@ -134,6 +136,8 @@ struct FXS_priv_data {
|
||||
xpp_line_t want_dtmf_events; /* what dahdi want */
|
||||
xpp_line_t want_dtmf_mute; /* what dahdi want */
|
||||
xpp_line_t prev_key_down; /* DTMF down sets the bit */
|
||||
xpp_line_t neon_blinking;
|
||||
xpp_line_t vbat_h; /* High voltage */
|
||||
struct timeval prev_key_time[CHANNELS_PERXPD];
|
||||
int led_counter[NUM_LEDS][CHANNELS_PERXPD];
|
||||
int ohttimer[CHANNELS_PERXPD];
|
||||
@@ -156,24 +160,48 @@ struct FXS_priv_data {
|
||||
#define LED_BLINK_RING (1000/8) /* in ticks */
|
||||
|
||||
/*---------------- FXS: Static functions ----------------------------------*/
|
||||
static int linefeed_control(xbus_t *xbus, xpd_t *xpd, lineno_t chan, enum fxs_state value)
|
||||
{
|
||||
struct FXS_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
LINE_DBG(SIGNAL, xpd, chan, "value=0x%02X\n", value);
|
||||
priv->lasttxhook[chan] = value;
|
||||
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
|
||||
}
|
||||
|
||||
static int do_chan_power(xbus_t *xbus, xpd_t *xpd, lineno_t chan, bool on)
|
||||
{
|
||||
int value = (on) ? REG_BATTERY_BATSL : 0x00;
|
||||
struct FXS_priv_data *priv;
|
||||
unsigned long *p;
|
||||
int was;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
BUG_ON(!xpd);
|
||||
priv = xpd->priv;
|
||||
p = (unsigned long *)&priv->vbat_h;
|
||||
if (on)
|
||||
was = test_and_set_bit(chan, p) != 0;
|
||||
else
|
||||
was = test_and_clear_bit(chan, p) != 0;
|
||||
if (was == on) {
|
||||
LINE_DBG(SIGNAL, xpd, chan,
|
||||
"%s (same, ignored)\n", (on) ? "up" : "down");
|
||||
return 0;
|
||||
}
|
||||
LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on) ? "up" : "down");
|
||||
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY, value);
|
||||
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, REG_BATTERY,
|
||||
(on) ? REG_BATTERY_BATSL : 0x00);
|
||||
}
|
||||
|
||||
static int linefeed_control(xbus_t *xbus, xpd_t *xpd, lineno_t chan, enum fxs_state value)
|
||||
{
|
||||
struct FXS_priv_data *priv;
|
||||
bool want_vbat_h;
|
||||
|
||||
priv = xpd->priv;
|
||||
/*
|
||||
* Should we drop vbat_h only during actuall ring?
|
||||
* - It would lower the noise caused to other channels by
|
||||
* group ringing
|
||||
* - But it may also stop CallerID from passing through the SLIC
|
||||
*/
|
||||
want_vbat_h = value == FXS_LINE_RING;
|
||||
if (lower_ringing_noise || want_vbat_h)
|
||||
do_chan_power(xbus, xpd, chan, want_vbat_h);
|
||||
LINE_DBG(SIGNAL, xpd, chan, "value=0x%02X\n", value);
|
||||
priv->lasttxhook[chan] = value;
|
||||
return SLIC_DIRECT_REQUEST(xbus, xpd, chan, SLIC_WRITE, 0x40, value);
|
||||
}
|
||||
|
||||
static void vmwi_search(xpd_t *xpd, lineno_t pos, bool on)
|
||||
@@ -386,6 +414,8 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
|
||||
int regular_channels;
|
||||
struct FXS_priv_data *priv;
|
||||
int i;
|
||||
int d_inputs = 0;
|
||||
int d_outputs = 0;
|
||||
|
||||
if(!to_phone) {
|
||||
XBUS_NOTICE(xbus,
|
||||
@@ -398,16 +428,30 @@ static xpd_t *FXS_card_new(xbus_t *xbus, int unit, int subunit, const xproto_tab
|
||||
else
|
||||
regular_channels = min(8, subunit_ports);
|
||||
channels = regular_channels;
|
||||
if(unit == 0 && subtype != 4)
|
||||
/* Calculate digital inputs/outputs */
|
||||
if(unit == 0 && subtype != 4) {
|
||||
channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */
|
||||
d_inputs = LINES_DIGI_INP;
|
||||
d_outputs = LINES_DIGI_OUT;
|
||||
}
|
||||
xpd = xpd_alloc(xbus, unit, subunit, subtype, subunits, sizeof(struct FXS_priv_data), proto_table, channels);
|
||||
if(!xpd)
|
||||
return NULL;
|
||||
if(unit == 0) {
|
||||
XBUS_DBG(GENERAL, xbus, "First XPD detected. Initialize digital outputs/inputs\n");
|
||||
PHONEDEV(xpd).digital_outputs = BITMASK(LINES_DIGI_OUT) << regular_channels;
|
||||
PHONEDEV(xpd).digital_inputs = BITMASK(LINES_DIGI_INP) << (regular_channels + LINES_DIGI_OUT);
|
||||
}
|
||||
/* Initialize digital inputs/outputs */
|
||||
if (d_inputs) {
|
||||
XBUS_DBG(GENERAL, xbus, "Initialize %d digital inputs\n",
|
||||
d_inputs);
|
||||
PHONEDEV(xpd).digital_inputs =
|
||||
BITMASK(d_inputs) << (regular_channels + d_outputs);
|
||||
} else
|
||||
XBUS_DBG(GENERAL, xbus, "No digital inputs\n");
|
||||
if (d_outputs) {
|
||||
XBUS_DBG(GENERAL, xbus, "Initialize %d digital outputs\n",
|
||||
d_outputs);
|
||||
PHONEDEV(xpd).digital_outputs =
|
||||
BITMASK(d_outputs) << regular_channels;
|
||||
} else
|
||||
XBUS_DBG(GENERAL, xbus, "No digital outputs\n");
|
||||
PHONEDEV(xpd).direction = TO_PHONE;
|
||||
xpd->type_name = "FXS";
|
||||
if(fxs_proc_create(xbus, xpd) < 0)
|
||||
@@ -548,12 +592,16 @@ static int FXS_card_dahdi_postregistration(xpd_t *xpd, bool on)
|
||||
*/
|
||||
static void __do_mute_dtmf(xpd_t *xpd, int pos, bool muteit)
|
||||
{
|
||||
struct FXS_priv_data *priv;
|
||||
|
||||
priv = xpd->priv;
|
||||
LINE_DBG(SIGNAL, xpd, pos, "%s\n", (muteit) ? "MUTE" : "UNMUTE");
|
||||
if(muteit)
|
||||
BIT_SET(PHONEDEV(xpd).mute_dtmf, pos);
|
||||
else
|
||||
BIT_CLR(PHONEDEV(xpd).mute_dtmf, pos);
|
||||
CALL_PHONE_METHOD(card_pcm_recompute, xpd, 0); /* already spinlocked */
|
||||
/* already spinlocked */
|
||||
CALL_PHONE_METHOD(card_pcm_recompute, xpd, priv->search_fsk_pattern);
|
||||
}
|
||||
|
||||
static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
@@ -568,6 +616,7 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
if (VMWI_NEON(priv, pos) && msg_waiting) {
|
||||
/* A write to register 0x40 will now turn on/off the VM led */
|
||||
LINE_DBG(SIGNAL, xpd, pos, "NEON\n");
|
||||
BIT_SET(priv->neon_blinking, pos);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0xE8, 0x03);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0xEF, 0x7B);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x14, 0x9F, 0x00);
|
||||
@@ -602,6 +651,7 @@ static int set_vm_led_mode(xbus_t *xbus, xpd_t *xpd, int pos,
|
||||
} else {
|
||||
/* A write to register 0x40 will now turn on/off the ringer */
|
||||
LINE_DBG(SIGNAL, xpd, pos, "RINGER\n");
|
||||
BIT_CLR(priv->neon_blinking, pos);
|
||||
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x16, 0x00, 0x00);
|
||||
ret += SLIC_INDIRECT_REQUEST(xbus, xpd, pos, SLIC_WRITE, 0x15, 0x77, 0x01);
|
||||
@@ -668,7 +718,7 @@ static int send_ring(xpd_t *xpd, lineno_t chan, bool on)
|
||||
LINE_DBG(SIGNAL, xpd, chan, "%s\n", (on)?"on":"off");
|
||||
priv = xpd->priv;
|
||||
set_vm_led_mode(xbus, xpd, chan, 0);
|
||||
do_chan_power(xbus, xpd, chan, on); // Power up (for ring)
|
||||
do_chan_power(xbus, xpd, chan, on); /* Power up (for ring) */
|
||||
ret = linefeed_control(xbus, xpd, chan, value);
|
||||
if(on) {
|
||||
MARK_BLINK(priv, chan, LED_GREEN, LED_BLINK_RING);
|
||||
@@ -861,7 +911,8 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
if (IS_SET(PHONEDEV(xpd).digital_inputs | PHONEDEV(xpd).digital_outputs, pos))
|
||||
return 0; /* Nothing to do */
|
||||
oht_pcm(xpd, pos, 1); /* Get ready of VMWI FSK tones */
|
||||
if(priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE) {
|
||||
if (priv->lasttxhook[pos] == FXS_LINE_POL_ACTIVE ||
|
||||
IS_SET(priv->neon_blinking, pos)) {
|
||||
priv->ohttimer[pos] = val;
|
||||
priv->idletxhookstate[pos] = FXS_LINE_POL_OHTRANS;
|
||||
vmwi_search(xpd, pos, 1);
|
||||
@@ -924,10 +975,25 @@ static int FXS_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
case DAHDI_SETPOLARITY:
|
||||
if (get_user(val, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
/* Can't change polarity while ringing or when open */
|
||||
/*
|
||||
* Asterisk may send us this if chan_dahdi config
|
||||
* has "hanguponpolarityswitch=yes" to notify
|
||||
* that the other side has hanged up.
|
||||
*
|
||||
* This has no effect on normal phone (but we may
|
||||
* be connected to another FXO equipment).
|
||||
* note that this chan_dahdi settings has different
|
||||
* meaning for FXO, where it signals polarity
|
||||
* reversal *detection* logic.
|
||||
*
|
||||
* It seems that sometimes we get this from
|
||||
* asterisk in wrong state (e.g: while ringing).
|
||||
* In these cases, silently ignore it.
|
||||
*/
|
||||
if (priv->lasttxhook[pos] == FXS_LINE_RING || priv->lasttxhook[pos] == FXS_LINE_OPEN) {
|
||||
LINE_ERR(xpd, pos, "DAHDI_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n",
|
||||
(val)?"ON":"OFF", priv->lasttxhook[pos]);
|
||||
LINE_DBG(SIGNAL, xpd, pos,
|
||||
"DAHDI_SETPOLARITY: %s Cannot change when lasttxhook=0x%X\n",
|
||||
(val)?"ON":"OFF", priv->lasttxhook[pos]);
|
||||
return -EINVAL;
|
||||
}
|
||||
LINE_DBG(SIGNAL, xpd, pos, "DAHDI_SETPOLARITY: %s\n", (val)?"ON":"OFF");
|
||||
@@ -1029,7 +1095,8 @@ static void handle_linefeed(xpd_t *xpd)
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
for_each_line(xpd, i) {
|
||||
if (priv->lasttxhook[i] == FXS_LINE_RING) {
|
||||
if (priv->lasttxhook[i] == FXS_LINE_RING &&
|
||||
!IS_SET(priv->neon_blinking, i)) {
|
||||
/* RINGing, prepare for OHT */
|
||||
priv->ohttimer[i] = OHT_TIMER;
|
||||
priv->idletxhookstate[i] = FXS_LINE_POL_OHTRANS;
|
||||
@@ -1142,7 +1209,7 @@ static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
#ifdef POLL_DIGITAL_INPUTS
|
||||
if(poll_digital_inputs && xpd->xbus_idx == 0) {
|
||||
if (poll_digital_inputs && PHONEDEV(xpd).digital_inputs) {
|
||||
if((xpd->timer_count % poll_digital_inputs) == 0)
|
||||
poll_inputs(xpd);
|
||||
}
|
||||
@@ -1254,6 +1321,13 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
||||
bool offhook = (REG_FIELD(info, data_low) & 0x1) == 0;
|
||||
xpp_line_t lines = BIT(info->portnum);
|
||||
|
||||
/* Sanity check */
|
||||
if (!PHONEDEV(xpd).digital_inputs) {
|
||||
XPD_NOTICE(xpd,
|
||||
"%s called without digital inputs. Ignored\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
/* Map SLIC number into line number */
|
||||
for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
|
||||
int channo = input_channels[i];
|
||||
@@ -1277,7 +1351,8 @@ static void process_digital_inputs(xpd_t *xpd, const reg_cmd_t *info)
|
||||
#endif
|
||||
|
||||
static const char dtmf_digits[] = {
|
||||
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '*', '#', 'A', 'B', 'C', 'D'
|
||||
'D', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '*', '#',
|
||||
'A', 'B', 'C'
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1299,12 +1374,6 @@ static void process_dtmf(xpd_t *xpd, uint portnum, byte val)
|
||||
return;
|
||||
priv = xpd->priv;
|
||||
val &= 0xF;
|
||||
if(val <= 0) {
|
||||
if(key_down)
|
||||
XPD_NOTICE(xpd, "Bad DTMF value %d. Ignored\n", val);
|
||||
return;
|
||||
}
|
||||
val--;
|
||||
digit = dtmf_digits[val];
|
||||
want_mute = IS_SET(priv->want_dtmf_mute, portnum);
|
||||
want_event = IS_SET(priv->want_dtmf_events, portnum);
|
||||
@@ -1366,7 +1435,7 @@ static int FXS_card_register_reply(xbus_t *xbus, xpd_t *xpd, reg_cmd_t *info)
|
||||
/*
|
||||
* Process digital inputs polling results
|
||||
*/
|
||||
else if(xpd->xbus_idx == 0 && !indirect && regnum == REG_DIGITAL_IOCTRL) {
|
||||
else if (!indirect && regnum == REG_DIGITAL_IOCTRL) {
|
||||
process_digital_inputs(xpd, info);
|
||||
}
|
||||
#endif
|
||||
@@ -1481,11 +1550,13 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
|
||||
spin_lock_irqsave(&xpd->lock, flags);
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!priv);
|
||||
len += sprintf(page + len, "%-8s %-10s %-10s %-10s\n",
|
||||
len += sprintf(page + len, "%-8s %-10s %-10s %-10s %-10s %-10s\n",
|
||||
"Channel",
|
||||
"idletxhookstate",
|
||||
"lasttxhook",
|
||||
"ohttimer"
|
||||
"ohttimer",
|
||||
"neon_blinking",
|
||||
"search_fsk_pattern"
|
||||
);
|
||||
for_each_line(xpd, i) {
|
||||
char pref;
|
||||
@@ -1496,14 +1567,21 @@ static int proc_fxs_info_read(char *page, char **start, off_t off, int count, in
|
||||
pref = 'I';
|
||||
else
|
||||
pref = ' ';
|
||||
len += sprintf(page + len, "%c%7d %10d %10d %10d\n",
|
||||
len += sprintf(page + len, "%c%7d %10d %10d %10d %10d %10d\n",
|
||||
pref,
|
||||
i,
|
||||
priv->idletxhookstate[i],
|
||||
priv->lasttxhook[i],
|
||||
priv->ohttimer[i]
|
||||
priv->ohttimer[i],
|
||||
IS_SET(priv->neon_blinking, i),
|
||||
IS_SET(priv->search_fsk_pattern, i)
|
||||
);
|
||||
}
|
||||
len += sprintf(page + len, "\n%-12s", "vbat_h:");
|
||||
for_each_line(xpd, i) {
|
||||
len += sprintf(page + len, "%4d",
|
||||
test_bit(i, (unsigned long *)&priv->vbat_h));
|
||||
}
|
||||
len += sprintf(page + len, "\n");
|
||||
for(led = 0; led < NUM_LEDS; led++) {
|
||||
len += sprintf(page + len, "LED #%d", led);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
enum fxs_opcodes {
|
||||
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 */
|
||||
|
||||
@@ -40,6 +40,36 @@ extern int debug;
|
||||
|
||||
/*---------------- GLOBAL PROC handling -----------------------------------*/
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* Zero length multibyte is legal and has special meaning for the
|
||||
* firmware:
|
||||
* eoftx==1: Start sending us D-channel packets.
|
||||
* eoftx==0: Stop sending us D-channel packets.
|
||||
*/
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = 0;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = portno;
|
||||
reg_cmd->eoframe = eoftx;
|
||||
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
||||
if (debug & DBG_REGS)
|
||||
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__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int parse_hexbyte(const char *buf)
|
||||
{
|
||||
char *endp;
|
||||
@@ -155,8 +185,8 @@ static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
|
||||
addr_mode, argc - argno);
|
||||
goto out;
|
||||
}
|
||||
ret = send_multibyte_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm', NULL, 0);
|
||||
ret = send_magic_request(xpd->xbus, xpd->addr.unit, portno,
|
||||
addr_mode == 'm');
|
||||
goto out;
|
||||
}
|
||||
/* Normal (non-Magic) register commands */
|
||||
@@ -370,44 +400,6 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int send_multibyte_request(xbus_t *xbus,
|
||||
unsigned unit, xportno_t portno,
|
||||
bool eoftx, byte *buf, unsigned len)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
reg_cmd_t *reg_cmd;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Zero length multibyte is legal and has special meaning for the
|
||||
* firmware:
|
||||
* eoftx==1: Start sending us D-channel packets.
|
||||
* eoftx==0: Stop sending us D-channel packets.
|
||||
*/
|
||||
if(len > MULTIBYTE_MAX_LEN) {
|
||||
PORT_ERR(xbus, unit, portno, "%s: len=%d is too long. dropping.\n", __FUNCTION__, len);
|
||||
return -EINVAL;
|
||||
}
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, unit);
|
||||
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
|
||||
reg_cmd->bytes = len;
|
||||
reg_cmd->is_multibyte = 1;
|
||||
reg_cmd->portnum = portno;
|
||||
reg_cmd->eoframe = eoftx;
|
||||
if(len > 0) {
|
||||
memcpy(REG_XDATA(reg_cmd), (byte *)buf, len);
|
||||
} else {
|
||||
PORT_DBG(REGS, xbus, unit, portno, "Magic Packet (eoftx=%d)\n", eoftx);
|
||||
}
|
||||
if(debug & DBG_REGS)
|
||||
dump_xframe(__FUNCTION__, xbus, xframe, debug);
|
||||
ret = send_cmd_frame(xbus, xframe);
|
||||
if(ret < 0)
|
||||
PORT_ERR(xbus, unit, portno, "%s: failed sending xframe\n", __FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The XPD parameter is totaly ignored by the driver and firmware as well.
|
||||
*/
|
||||
@@ -430,19 +422,37 @@ int send_multibyte_request(xbus_t *xbus,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0x23 */ HOSTCMD(GLOBAL, RESET_SYNC_COUNTERS)
|
||||
/*
|
||||
* Wrapper for different types of xbus reset
|
||||
*/
|
||||
static int send_xbus_reset(xbus_t *xbus, uint8_t reset_mask)
|
||||
{
|
||||
xframe_t *xframe;
|
||||
xpacket_t *pack;
|
||||
|
||||
BUG_ON(!xbus);
|
||||
//XBUS_DBG(SYNC, xbus, "\n");
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, RESET_SYNC_COUNTERS, 0);
|
||||
RPACKET_FIELD(pack, GLOBAL, RESET_SYNC_COUNTERS, mask) = 0x10;
|
||||
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, XBUS_RESET, 0);
|
||||
RPACKET_FIELD(pack, GLOBAL, XBUS_RESET, mask) = reset_mask;
|
||||
send_cmd_frame(xbus, xframe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0x23 */ HOSTCMD(GLOBAL, RESET_SPI)
|
||||
{
|
||||
XBUS_DBG(DEVICES, xbus, "Sending SPI reset\n");
|
||||
/* toggle reset line */
|
||||
send_xbus_reset(xbus, 0x04);
|
||||
send_xbus_reset(xbus, 0x00);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 0x23 */ HOSTCMD(GLOBAL, RESET_SYNC_COUNTERS)
|
||||
{
|
||||
//XBUS_DBG(SYNC, xbus, "\n");
|
||||
return send_xbus_reset(xbus, 0x10);
|
||||
}
|
||||
|
||||
/*---------------- GLOBAL: Astribank Reply Handlers -----------------------*/
|
||||
|
||||
HANDLER_DEF(GLOBAL, NULL_REPLY)
|
||||
@@ -534,6 +544,7 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION) /* 0x08 */
|
||||
list_add_tail(&card_desc->card_list, &worker->card_list);
|
||||
spin_unlock_irqrestore(&worker->worker_lock, flags);
|
||||
}
|
||||
CALL_PROTO(GLOBAL, RESET_SPI, xbus, NULL);
|
||||
if (!xbus_process_worker(xbus)) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
@@ -642,7 +653,6 @@ static void global_packet_dump(const char *msg, xpacket_t *pack)
|
||||
DBG(GENERAL, "%s\n", msg);
|
||||
}
|
||||
|
||||
#define MAX_ENV_STR 40
|
||||
#define MAX_PATH_STR 128
|
||||
|
||||
int run_initialize_registers(xpd_t *xpd)
|
||||
@@ -651,6 +661,7 @@ int run_initialize_registers(xpd_t *xpd)
|
||||
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];
|
||||
@@ -668,6 +679,7 @@ int run_initialize_registers(xpd_t *xpd)
|
||||
char *envp[] = {
|
||||
busstr,
|
||||
busnumstr,
|
||||
modelstr,
|
||||
unitstr,
|
||||
subunitsstr,
|
||||
typestr,
|
||||
@@ -703,6 +715,7 @@ int run_initialize_registers(xpd_t *xpd)
|
||||
}
|
||||
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(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);
|
||||
@@ -750,4 +763,3 @@ err:
|
||||
EXPORT_SYMBOL(sync_mode_name);
|
||||
EXPORT_SYMBOL(run_initialize_registers);
|
||||
EXPORT_SYMBOL(xpp_register_request);
|
||||
EXPORT_SYMBOL(send_multibyte_request);
|
||||
|
||||
@@ -38,7 +38,7 @@ enum global_opcodes {
|
||||
XPROTO_NAME(GLOBAL, SYNC_REPLY) = 0x1A,
|
||||
/**/
|
||||
XPROTO_NAME(GLOBAL, ERROR_CODE) = 0x22,
|
||||
XPROTO_NAME(GLOBAL, RESET_SYNC_COUNTERS) = 0x23,
|
||||
XPROTO_NAME(GLOBAL, XBUS_RESET) = 0x23,
|
||||
XPROTO_NAME(GLOBAL, NULL_REPLY) = 0xFE,
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ DEF_RPACKET_DATA(GLOBAL, SYNC_REPLY,
|
||||
DEF_RPACKET_DATA(GLOBAL, REGISTER_REPLY,
|
||||
reg_cmd_t regcmd;
|
||||
);
|
||||
DEF_RPACKET_DATA(GLOBAL, RESET_SYNC_COUNTERS,
|
||||
DEF_RPACKET_DATA(GLOBAL, XBUS_RESET,
|
||||
byte mask;
|
||||
);
|
||||
DEF_RPACKET_DATA(GLOBAL, ERROR_CODE,
|
||||
@@ -98,6 +98,7 @@ DEF_RPACKET_DATA(GLOBAL, ERROR_CODE,
|
||||
|
||||
/* 0x07 */ DECLARE_CMD(GLOBAL, AB_REQUEST);
|
||||
/* 0x19 */ DECLARE_CMD(GLOBAL, SYNC_SOURCE, enum sync_mode mode, int drift);
|
||||
/* 0x23 */ DECLARE_CMD(GLOBAL, RESET_SPI);
|
||||
/* 0x23 */ DECLARE_CMD(GLOBAL, RESET_SYNC_COUNTERS);
|
||||
|
||||
int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
|
||||
|
||||
@@ -80,6 +80,7 @@ static int pri_shutdown(struct dahdi_span *span);
|
||||
static int pri_rbsbits(struct dahdi_chan *chan, int bits);
|
||||
static int pri_lineconfig(xpd_t *xpd, int lineconfig);
|
||||
static void send_idlebits(xpd_t *xpd, bool saveold);
|
||||
static int apply_pri_protocol(xpd_t *xpd);
|
||||
|
||||
#define PROC_REGISTER_FNAME "slics"
|
||||
|
||||
@@ -90,17 +91,29 @@ enum pri_protocol {
|
||||
PRI_PROTO_J1 = 3
|
||||
};
|
||||
|
||||
static const char *protocol_names[] = {
|
||||
[PRI_PROTO_0] = "??", /* unknown */
|
||||
[PRI_PROTO_E1] = "E1",
|
||||
[PRI_PROTO_T1] = "T1",
|
||||
[PRI_PROTO_J1] = "J1"
|
||||
};
|
||||
|
||||
static const char *pri_protocol_name(enum pri_protocol pri_protocol)
|
||||
{
|
||||
static const char *protocol_names[] = {
|
||||
[PRI_PROTO_0] = "??", /* unknown */
|
||||
[PRI_PROTO_E1] = "E1",
|
||||
[PRI_PROTO_T1] = "T1",
|
||||
[PRI_PROTO_J1] = "J1"
|
||||
};
|
||||
return protocol_names[pri_protocol];
|
||||
}
|
||||
|
||||
static enum pri_protocol pri_protocol_bystr(const char *spantype)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(protocol_names); i++) {
|
||||
if (strcasecmp(protocol_names[i], spantype) == 0)
|
||||
return i;
|
||||
}
|
||||
return PRI_PROTO_0;
|
||||
}
|
||||
|
||||
static int pri_num_channels(enum pri_protocol pri_protocol)
|
||||
{
|
||||
static int num_channels[] = {
|
||||
@@ -551,12 +564,14 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto)
|
||||
unsigned int dchan_num;
|
||||
int default_lineconfig = 0;
|
||||
int ret;
|
||||
struct phonedev *phonedev;
|
||||
|
||||
BUG_ON(!xpd);
|
||||
priv = xpd->priv;
|
||||
if(SPAN_REGISTERED(xpd)) {
|
||||
XPD_NOTICE(xpd, "Registered as span %d. Cannot do setup pri protocol (%s)\n",
|
||||
PHONEDEV(xpd).span.spanno, __FUNCTION__);
|
||||
phonedev = &PHONEDEV(xpd);
|
||||
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &phonedev->span.flags)) {
|
||||
XPD_NOTICE(xpd, "%s: %s already assigned as span %d\n",
|
||||
__func__, phonedev->span.name, phonedev->span.spanno);
|
||||
return -EBUSY;
|
||||
}
|
||||
if(priv->pri_protocol != PRI_PROTO_0) {
|
||||
@@ -596,8 +611,8 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto)
|
||||
}
|
||||
priv->pri_protocol = set_proto;
|
||||
priv->is_cas = -1;
|
||||
PHONEDEV(xpd).channels = pri_num_channels(set_proto);
|
||||
PHONEDEV(xpd).offhook_state = BITMASK(PHONEDEV(xpd).channels);
|
||||
phonedev->channels = pri_num_channels(set_proto);
|
||||
phonedev->offhook_state = BITMASK(phonedev->channels);
|
||||
CALL_PHONE_METHOD(card_pcm_recompute, xpd, 0);
|
||||
priv->deflaw = deflaw;
|
||||
priv->dchan_num = dchan_num;
|
||||
@@ -605,7 +620,7 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto)
|
||||
xpd->type_name = type_name(priv->pri_protocol);
|
||||
XPD_DBG(GENERAL, xpd, "%s, channels=%d, dchan_num=%d, deflaw=%d\n",
|
||||
pri_protocol_name(set_proto),
|
||||
PHONEDEV(xpd).channels,
|
||||
phonedev->channels,
|
||||
priv->dchan_num,
|
||||
priv->deflaw
|
||||
);
|
||||
@@ -618,7 +633,7 @@ static int set_pri_proto(xpd_t *xpd, enum pri_protocol set_proto)
|
||||
XPD_NOTICE(xpd, "Failed setting PRI default line config\n");
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
return apply_pri_protocol(xpd);
|
||||
}
|
||||
|
||||
static void dahdi_update_syncsrc(xpd_t *xpd)
|
||||
@@ -1019,6 +1034,17 @@ static int pri_lineconfig(xpd_t *xpd, int lineconfig)
|
||||
}
|
||||
#endif
|
||||
if(force_cas) {
|
||||
if(priv->pri_protocol == PRI_PROTO_E1) {
|
||||
int rs1 = 0x0B;
|
||||
|
||||
/*
|
||||
* Set correct X1-X3 bits in the E1 CAS MFAS
|
||||
* They are unused in E1 and should be 1
|
||||
*/
|
||||
XPD_DBG(GENERAL, xpd, "%s: rs1(0x%02X) = 0x%02X\n",
|
||||
__FUNCTION__, REG_RS1_E, rs1);
|
||||
write_subunit(xpd, REG_RS1_E, rs1);
|
||||
}
|
||||
xsp |= REG_XSP_E_CASEN; /* Same as REG_FMR5_T_EIBR for T1 */
|
||||
}
|
||||
XPD_DBG(GENERAL, xpd, "%s: xsp(0x%02X) = 0x%02X\n", __FUNCTION__, REG_XSP_E, xsp);
|
||||
@@ -1029,6 +1055,17 @@ bad_lineconfig:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int pri_set_spantype(struct dahdi_span *span, const char *spantype)
|
||||
{
|
||||
struct phonedev *phonedev = container_of(span, struct phonedev, span);
|
||||
xpd_t *xpd = container_of(phonedev, struct xpd, phonedev);
|
||||
enum pri_protocol set_proto = PRI_PROTO_0;
|
||||
|
||||
XPD_INFO(xpd, "%s: %s\n", __func__, spantype);
|
||||
set_proto = pri_protocol_bystr(spantype);
|
||||
return set_pri_proto(xpd, set_proto);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called only for 'span' keyword in /etc/dahdi/system.conf
|
||||
*/
|
||||
@@ -1204,6 +1241,7 @@ static int pri_audio_notify(struct dahdi_chan *chan, int on)
|
||||
|
||||
static const struct dahdi_span_ops PRI_span_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.set_spantype = pri_set_spantype,
|
||||
.spanconfig = pri_spanconfig,
|
||||
.chanconfig = pri_chanconfig,
|
||||
.startup = pri_startup,
|
||||
@@ -1215,6 +1253,7 @@ static const struct dahdi_span_ops PRI_span_ops = {
|
||||
.maint = xpp_maint,
|
||||
.echocan_create = xpp_echocan_create,
|
||||
.echocan_name = xpp_echocan_name,
|
||||
.assigned = xpp_span_assigned,
|
||||
#ifdef DAHDI_SYNC_TICK
|
||||
.sync_tick = dahdi_sync_tick,
|
||||
#endif
|
||||
@@ -1227,7 +1266,7 @@ static const struct dahdi_span_ops PRI_span_ops = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
static int apply_pri_protocol(xpd_t *xpd)
|
||||
{
|
||||
xbus_t *xbus;
|
||||
struct PRI_priv_data *priv;
|
||||
@@ -1237,15 +1276,7 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
xbus = xpd->xbus;
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!xbus);
|
||||
XPD_DBG(GENERAL, xpd, "%s (proto=%s, channels=%d, deflaw=%d)\n",
|
||||
(on)?"on":"off",
|
||||
pri_protocol_name(priv->pri_protocol),
|
||||
PHONEDEV(xpd).channels,
|
||||
priv->deflaw);
|
||||
if(!on) {
|
||||
/* Nothing to do yet */
|
||||
return 0;
|
||||
}
|
||||
XPD_DBG(GENERAL, xpd, "\n");
|
||||
PHONEDEV(xpd).span.spantype = pri_protocol_name(priv->pri_protocol);
|
||||
PHONEDEV(xpd).span.linecompat = pri_linecompat(priv->pri_protocol);
|
||||
PHONEDEV(xpd).span.deflaw = priv->deflaw;
|
||||
@@ -1268,9 +1299,32 @@ static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
}
|
||||
PHONEDEV(xpd).offhook_state = PHONEDEV(xpd).wanted_pcm_mask;
|
||||
PHONEDEV(xpd).span.ops = &PRI_span_ops;
|
||||
PHONEDEV(xpd).span.channels = PHONEDEV(xpd).channels;
|
||||
xpd_set_spanname(xpd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PRI_card_dahdi_preregistration(xpd_t *xpd, bool on)
|
||||
{
|
||||
xbus_t *xbus;
|
||||
struct PRI_priv_data *priv;
|
||||
|
||||
BUG_ON(!xpd);
|
||||
xbus = xpd->xbus;
|
||||
priv = xpd->priv;
|
||||
BUG_ON(!xbus);
|
||||
XPD_DBG(GENERAL, xpd, "%s (proto=%s, channels=%d, deflaw=%d)\n",
|
||||
(on)?"on":"off",
|
||||
pri_protocol_name(priv->pri_protocol),
|
||||
PHONEDEV(xpd).channels,
|
||||
priv->deflaw);
|
||||
if(!on) {
|
||||
/* Nothing to do yet */
|
||||
return 0;
|
||||
}
|
||||
return apply_pri_protocol(xpd);
|
||||
}
|
||||
|
||||
static int PRI_card_dahdi_postregistration(xpd_t *xpd, bool on)
|
||||
{
|
||||
xbus_t *xbus;
|
||||
@@ -1424,14 +1478,17 @@ static int PRI_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
return -ENODEV;
|
||||
chan = XPD_CHAN(xpd, pos);
|
||||
switch (cmd) {
|
||||
/*
|
||||
* Asterisk may send FXS type ioctl()'s to us:
|
||||
* - Some are sent to everybody (DAHDI_TONEDETECT)
|
||||
* - Some are sent because we may be in CAS mode
|
||||
* (FXS signalling)
|
||||
* Ignore them.
|
||||
*/
|
||||
case DAHDI_TONEDETECT:
|
||||
/*
|
||||
* Asterisk call all span types with this (FXS specific)
|
||||
* call. Silently ignore it.
|
||||
*/
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: TONEDETECT (%s)\n",
|
||||
(chan->flags & DAHDI_FLAG_AUDIO) ?
|
||||
"AUDIO" : "SILENCE");
|
||||
"AUDIO" : "SILENCE");
|
||||
return -ENOTTY;
|
||||
case DAHDI_ONHOOKTRANSFER:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: ONHOOKTRANSFER\n");
|
||||
@@ -1442,6 +1499,10 @@ static int PRI_card_ioctl(xpd_t *xpd, int pos, unsigned int cmd, unsigned long a
|
||||
case DAHDI_VMWI_CONFIG:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: VMWI_CONFIG\n");
|
||||
return -ENOTTY;
|
||||
case DAHDI_SETPOLARITY:
|
||||
LINE_DBG(SIGNAL, xpd, pos, "PRI: SETPOLARITY\n");
|
||||
return -ENOTTY;
|
||||
/* report on really bad ioctl()'s */
|
||||
default:
|
||||
report_bad_ioctl(THIS_MODULE->name, xpd, pos, cmd);
|
||||
return -ENOTTY;
|
||||
@@ -2210,19 +2271,20 @@ static DEVICE_ATTR_WRITER(pri_protocol_store, dev, buf, count)
|
||||
BUG_ON(!dev);
|
||||
xpd = dev_to_xpd(dev);
|
||||
XPD_DBG(GENERAL, xpd, "%s\n", buf);
|
||||
if(!xpd)
|
||||
if (!xpd)
|
||||
return -ENODEV;
|
||||
if((i = strcspn(buf, " \r\n")) != 2) {
|
||||
i = strcspn(buf, " \r\n");
|
||||
if (i != 2) {
|
||||
XPD_NOTICE(xpd,
|
||||
"Protocol name '%s' has %d characters (should be 2). Ignored.\n",
|
||||
buf, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
if(strnicmp(buf, "E1", 2) == 0)
|
||||
if (strnicmp(buf, "E1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_E1;
|
||||
else if(strnicmp(buf, "T1", 2) == 0)
|
||||
else if (strnicmp(buf, "T1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_T1;
|
||||
else if(strnicmp(buf, "J1", 2) == 0)
|
||||
else if (strnicmp(buf, "J1", 2) == 0)
|
||||
new_protocol = PRI_PROTO_J1;
|
||||
else {
|
||||
XPD_NOTICE(xpd,
|
||||
@@ -2234,7 +2296,8 @@ static DEVICE_ATTR_WRITER(pri_protocol_store, dev, buf, count)
|
||||
return (ret < 0) ? ret : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(pri_protocol, S_IRUGO | S_IWUSR, pri_protocol_show, pri_protocol_store);
|
||||
static DEVICE_ATTR(pri_protocol, S_IRUGO | S_IWUSR, pri_protocol_show,
|
||||
pri_protocol_store);
|
||||
|
||||
static DEVICE_ATTR_READER(pri_localloop_show, dev, buf)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
20685
drivers/dahdi/xpp/firmwares/FPGA_1161.201.hex
Normal file
20685
drivers/dahdi/xpp/firmwares/FPGA_1161.201.hex
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
||||
# Install firmwares and initialization scripts for the Astribank
|
||||
# drivers
|
||||
|
||||
FPGA_FW = FPGA_FXS.hex FPGA_1141.hex FPGA_1151.hex FPGA_1161.hex
|
||||
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
|
||||
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.hex $(FPGA_FW) $(PIC_FW) $(OCT_FW)
|
||||
FIRMWARES = $(USB_FW) $(FPGA_FW) $(PIC_FW) $(OCT_FW)
|
||||
PROTO_VER = 30
|
||||
SCRIPTS_BASE = $(patsubst %,init_card_%_$(PROTO_VER),1 2 3 4 5)
|
||||
SCRIPTS = $(SCRIPTS_BASE:%=../%)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# $Id: PIC_TYPE_1.hex 9732 2011-08-24 19:13:55Z dima $
|
||||
# $Id: PIC_TYPE_1.hex 9841 2011-09-08 17:00:23Z dima $
|
||||
#
|
||||
:03000000A1EA4A28
|
||||
:03000100C41C41DB
|
||||
@@ -31,8 +31,8 @@
|
||||
:03001B00D00D0005
|
||||
:03001C00A17A17AF
|
||||
:03001D0080080058
|
||||
:03001E00C0710BA3
|
||||
:03001F0016603830
|
||||
:03001E00C0010B13
|
||||
:03001F0019A038ED
|
||||
:03002000743C0627
|
||||
:03002100A26D804D
|
||||
:03002200C01024E7
|
||||
@@ -42,451 +42,445 @@
|
||||
:03002600C03030B7
|
||||
:0300270018C901F4
|
||||
:030028006432043B
|
||||
:03002900A4C03040
|
||||
:03002900A4A03060
|
||||
:03002A0020C901E9
|
||||
:03002B007432022A
|
||||
:03002C00AFA03052
|
||||
:03002D0020990116
|
||||
:03002E00021C8031
|
||||
:03002F00C40FFFFC
|
||||
:03003000D8016490
|
||||
:03003100024C106E
|
||||
:03003200C00FFFFD
|
||||
:0300330002215057
|
||||
:03003400201D0884
|
||||
:030035000306B906
|
||||
:03003600901D100A
|
||||
:0300370020402244
|
||||
:03003800030201BF
|
||||
:03003900901030F4
|
||||
:03003A0020290179
|
||||
:03003B00030204B9
|
||||
:03003C00901030F1
|
||||
:03003D00C11901E5
|
||||
:03003E00190202A2
|
||||
:03003F00643030FA
|
||||
:03004000A45901BF
|
||||
:03004100C22800D2
|
||||
:030042001902148C
|
||||
:03004300743E7098
|
||||
:03004400A483088A
|
||||
:03004500209308FD
|
||||
:030046001253084A
|
||||
:03004700A4B30857
|
||||
:03004800209027DE
|
||||
:03004900FFF800BD
|
||||
:03004A00165C0041
|
||||
:03004B00AFA0392A
|
||||
:03004C00209038C9
|
||||
:03004D00145C0739
|
||||
:03004E00643D40CE
|
||||
:03004F00A8C03412
|
||||
:03005000209C08E9
|
||||
:0300510002103862
|
||||
:03005200C40219CC
|
||||
:03005300D80E07BD
|
||||
:0300540002402047
|
||||
:03005500C0036085
|
||||
:0300560002236022
|
||||
:0300570020136013
|
||||
:030058000303603F
|
||||
:03005900901C10E8
|
||||
:03005A002040380B
|
||||
:03005B0003021984
|
||||
:03005C00901E07EC
|
||||
:03005D002021203F
|
||||
:03005E00030C1080
|
||||
:03005F009011807D
|
||||
:03006000C11E704E
|
||||
:0300610019074339
|
||||
:03006200643A728B
|
||||
:03006300A68C0266
|
||||
:03006400C2218036
|
||||
:03006500190E076A
|
||||
:03006600743643AA
|
||||
:03006700A8CA75AF
|
||||
:03006800209C03D6
|
||||
:0300690002118001
|
||||
:03006A00C44E077A
|
||||
:03006B00D8064371
|
||||
:03006C00024A75D0
|
||||
:03006D00C00C04C0
|
||||
:03006E00022180EC
|
||||
:03006F00201E0749
|
||||
:0300700003064341
|
||||
:03007100901A756D
|
||||
:03007200204C011E
|
||||
:030073000300384F
|
||||
:03007400901A746B
|
||||
:03007500202C1824
|
||||
:030076000300384C
|
||||
:03007700901219CB
|
||||
:03007800210E0F47
|
||||
:03007900E0303D37
|
||||
:03007A00743C00D3
|
||||
:03007B00C040384A
|
||||
:03007C00190C025A
|
||||
:03007D007481800B
|
||||
:03007E00A8CE0702
|
||||
:03007F00C0474334
|
||||
:03008000FFFA85FF
|
||||
:03008100150C3F1C
|
||||
:03008200643031B6
|
||||
:03008300A87C1640
|
||||
:03008400209A922D
|
||||
:0300850013EC0376
|
||||
:03008600A8A180AE
|
||||
:03008700209E07B1
|
||||
:03008800FFF7433C
|
||||
:0300890017EA8EE5
|
||||
:03008A0021ECFF67
|
||||
:03008B00035031EE
|
||||
:03008C00C14C184C
|
||||
:03008D00D80A92FC
|
||||
:03008E00024C031E
|
||||
:03008F00C000317D
|
||||
:03009000022C122D
|
||||
:03009100201A92A0
|
||||
:0300920003003C2C
|
||||
:03009300901E0FAD
|
||||
:0300940020409D6C
|
||||
:030095000307035B
|
||||
:03009600901A9C21
|
||||
:03009700202C0F0B
|
||||
:03009800030FFF54
|
||||
:0300990090115C67
|
||||
:03009A0021011D24
|
||||
:03009B00E01A9DCB
|
||||
:03009C0002721CD1
|
||||
:03009D00C18030EF
|
||||
:03009E00D80E0F6A
|
||||
:03009F0002403CE0
|
||||
:0300A000C00C028F
|
||||
:0300A10002203901
|
||||
:0300A200201C001F
|
||||
:0300A3000300391E
|
||||
:0300A400901C802D
|
||||
:0300A500204024D4
|
||||
:0300A600030C0840
|
||||
:0300A700901104B1
|
||||
:0300A800202039DC
|
||||
:0300A900030C0045
|
||||
:0300AA009010397A
|
||||
:0300AB00210C0025
|
||||
:0300AC0003B02678
|
||||
:0300AD00C140252A
|
||||
:0300AE0002403ECF
|
||||
:0300AF00C0102B53
|
||||
:0300B000022C031C
|
||||
:0300B10020102CF0
|
||||
:0300B200030C40FC
|
||||
:0300B30090103971
|
||||
:0300B4002047D909
|
||||
:0300B500030AB487
|
||||
:0300B600901C009B
|
||||
:0300B700207208AC
|
||||
:0300B80003003012
|
||||
:0300B9009019019A
|
||||
:0300BA0021AC80F6
|
||||
:0300BB0014120814
|
||||
:0300BC0070703031
|
||||
:0300BD00AC09018A
|
||||
:0300BE00181C40CB
|
||||
:0300BF00AC303929
|
||||
:0300C00069BC0117
|
||||
:0300C100AFA037B6
|
||||
:0300C200F00C60DF
|
||||
:0300C3002282C8CE
|
||||
:0300C400643AC3D8
|
||||
:0300C500AFAC00DD
|
||||
:0300C6001BA03745
|
||||
:0300C700C106D996
|
||||
:0300C800FFFACC70
|
||||
:0300C90017B6F96E
|
||||
:0300CA0021ABCF98
|
||||
:0300CB00141AC73D
|
||||
:0300CC0064394252
|
||||
:0300CD00AD0C0275
|
||||
:0300CE00C10180ED
|
||||
:0300CF0013BE0756
|
||||
:0300D000C507431E
|
||||
:0300D100039AEDA2
|
||||
:0300D200799C0610
|
||||
:0300D300AD2195C7
|
||||
:0300D40020B7430F
|
||||
:0300D500D00AED61
|
||||
:0300D6000387D3CA
|
||||
:0300D700219AED7E
|
||||
:0300D800E07C06C3
|
||||
:0300D900348187E8
|
||||
:0300DA0034874325
|
||||
:0300DB00348ADE86
|
||||
:0300DC00348C035E
|
||||
:0300DD00030AEB28
|
||||
:0300DE00206C078C
|
||||
:0300DF00348187E2
|
||||
:0300E0003487431F
|
||||
:0300E100348AE47A
|
||||
:0300E200348C015A
|
||||
:0300E300D05AEB05
|
||||
:0300E400031C03F7
|
||||
:0300E500C00187D0
|
||||
:0300E600032743AA
|
||||
:0300E700033AEAEF
|
||||
:0300E800C70C0042
|
||||
:0300E900039AEB8C
|
||||
:0300EA00C5020745
|
||||
:0300EB0003902758
|
||||
:0300EC00C18AFACC
|
||||
:0300ED00030C06FB
|
||||
:0300EE00C00195B9
|
||||
:0300EF00031643B2
|
||||
:0300F00021BAFA38
|
||||
:0300F100032C01DC
|
||||
:0300F200C001C783
|
||||
:0300F30003309C3B
|
||||
:0300F400C7070338
|
||||
:0300F500039AFA71
|
||||
:0300F600C50CFF37
|
||||
:0300F70003902251
|
||||
:0300F800C400271A
|
||||
:0300F900039B6204
|
||||
:0300FA00369C0031
|
||||
:0300FB00C016F339
|
||||
:0300FC001E6CFF78
|
||||
:0300FD0021C021FE
|
||||
:0300FE00086C018A
|
||||
:0300FF0074302436
|
||||
:03010000A1E90A68
|
||||
:030101000266B3E0
|
||||
:03010200C02B8986
|
||||
:03010300FFFC01FD
|
||||
:0301040016B02F03
|
||||
:03010500C0221500
|
||||
:0301060023E6D31A
|
||||
:03010700743D80C4
|
||||
:0301080012B0240E
|
||||
:0301090020B2170A
|
||||
:03010A000380224D
|
||||
:03010B00C44C06DB
|
||||
:03010C00039195C7
|
||||
:03010D00C40743E1
|
||||
:03010E00039B51FF
|
||||
:03010F00C006D354
|
||||
:03011000023B515E
|
||||
:03011100ABECE074
|
||||
:03011200B12157C1
|
||||
:03011300000643A0
|
||||
:03011400000B518C
|
||||
:03011500000C00DB
|
||||
:030116000007B728
|
||||
:03011700000C05D4
|
||||
:030118000007D706
|
||||
:03011900000C10C7
|
||||
:03011A000007F7E4
|
||||
:03011B00000C02D3
|
||||
:03011C00000027B9
|
||||
:03011D00000C10C3
|
||||
:03011E00000D02CF
|
||||
:03011F00000FFFCF
|
||||
:0301200000014299
|
||||
:030121000006973E
|
||||
:03012200000D02CB
|
||||
:030123000006379C
|
||||
:03012400000D10BB
|
||||
:03012500000022B5
|
||||
:03012600000C804A
|
||||
:03012700000124B0
|
||||
:03012800000C02C6
|
||||
:0301290000018052
|
||||
:03012A00000E07BD
|
||||
:03012B0000074387
|
||||
:03012C00000B3F86
|
||||
:03012D00000C05BE
|
||||
:03012E0000014786
|
||||
:03012F0000064384
|
||||
:03013000000B3F82
|
||||
:03013100000C01BE
|
||||
:0301320000018148
|
||||
:030133000007437F
|
||||
:03013400000B3885
|
||||
:03013500000C10AB
|
||||
:03013600000021A5
|
||||
:03013700000B3F7B
|
||||
:03013800000C10A8
|
||||
:0301390000018141
|
||||
:03013A0000074378
|
||||
:03013B00000B3F77
|
||||
:03013C00000C2094
|
||||
:03013D000000219E
|
||||
:03013E00000B3F74
|
||||
:03013F00000201BA
|
||||
:03002C00AE803073
|
||||
:03002D00C4090102
|
||||
:03002E00D80C806B
|
||||
:03002F00024FFF7E
|
||||
:03003000C00164A8
|
||||
:03003100022C108E
|
||||
:03003200209FFF0D
|
||||
:0300330003015076
|
||||
:03003400901D0814
|
||||
:030035002046B9A9
|
||||
:03003600030D10A7
|
||||
:0300370090102204
|
||||
:0300380020220182
|
||||
:0300390003003091
|
||||
:03003A0090190119
|
||||
:03003B00C11204EB
|
||||
:03003C0019003078
|
||||
:03003D0064390122
|
||||
:03003E00A43202E7
|
||||
:03003F00C22030AC
|
||||
:030040001909019A
|
||||
:0300410074380010
|
||||
:03004200A46214A1
|
||||
:03004300209E708C
|
||||
:030044001253084C
|
||||
:03004500A4930879
|
||||
:03004600209308FC
|
||||
:03004700FFF308BC
|
||||
:0300480016502728
|
||||
:03004900AE88007E
|
||||
:03004A00209C00F7
|
||||
:03004B0014503915
|
||||
:03004C00643038E5
|
||||
:03004D00A8603F69
|
||||
:03004E00C40C07D8
|
||||
:03004F00D80D4089
|
||||
:0300500002403437
|
||||
:03005100C00C08D8
|
||||
:0300520002203851
|
||||
:03005300209219DF
|
||||
:03005400030E0791
|
||||
:03005500901020E8
|
||||
:03005600204360E4
|
||||
:0300570003036040
|
||||
:03005800901360A2
|
||||
:0300590020236001
|
||||
:03005A00030C1084
|
||||
:03005B00901038CA
|
||||
:03005C00C11219B5
|
||||
:03005D00190E0772
|
||||
:03005E00643120EA
|
||||
:03005F00A64C109C
|
||||
:03006000C221803A
|
||||
:03006100190E7005
|
||||
:03006200743743AD
|
||||
:03006300A86A7315
|
||||
:03006400C44C0287
|
||||
:03006500D801803F
|
||||
:03006600024E0740
|
||||
:03006700C006438D
|
||||
:03006800022A76F3
|
||||
:03006900209C03D5
|
||||
:03006A000301800F
|
||||
:03006B00901E07DD
|
||||
:03006C00204643E8
|
||||
:03006D00030A760D
|
||||
:03006E00901C04DF
|
||||
:03006F00202180CD
|
||||
:03007000030E0775
|
||||
:03007100901643A3
|
||||
:03007200210A76EA
|
||||
:03007300E03C016D
|
||||
:03007400743038AD
|
||||
:03007500C04A7509
|
||||
:03007600190C184A
|
||||
:030077007480385A
|
||||
:03007800A8621962
|
||||
:03007900C04E0F67
|
||||
:03007A00FFF03D57
|
||||
:03007B00150C0061
|
||||
:03007C00643038B5
|
||||
:03007D00A81C02BA
|
||||
:03007E002091804E
|
||||
:03007F0013EE0776
|
||||
:03008000A847434B
|
||||
:03008100209A863C
|
||||
:03008200FFFC3F41
|
||||
:0300830017E03152
|
||||
:0300840021EC1656
|
||||
:03008500035A9388
|
||||
:03008600C14C0367
|
||||
:03008700D801801D
|
||||
:03008800024E071E
|
||||
:03008900C007436A
|
||||
:03008A00022A8FB8
|
||||
:03008B00209CFFB7
|
||||
:03008C000300313D
|
||||
:03008D00901C18AC
|
||||
:03008E00204A9372
|
||||
:03008F00030C035C
|
||||
:030090009010319C
|
||||
:03009100202C120E
|
||||
:03009200030A93CB
|
||||
:0300930090103C8E
|
||||
:03009400210E0F2B
|
||||
:0300950002709D59
|
||||
:03009600C147035C
|
||||
:03009700024A9D7D
|
||||
:03009800209C0F9A
|
||||
:03009900030FFF53
|
||||
:03009A0090115C66
|
||||
:03009B0020411DE4
|
||||
:03009C00030A9EB6
|
||||
:03009D0090121CA2
|
||||
:03009E002070309F
|
||||
:03009F00030E0F3E
|
||||
:0300A00090103C81
|
||||
:0300A100C18C020D
|
||||
:0300A200D800394A
|
||||
:0300A300024C000C
|
||||
:0300A400C0003960
|
||||
:0300A500022C80AA
|
||||
:0300A60020902483
|
||||
:0300A700030C083F
|
||||
:0300A800901104B0
|
||||
:0300A900204039BB
|
||||
:0300AA00030C0044
|
||||
:0300AB0090103979
|
||||
:0300AC00202C0005
|
||||
:0300AD0003003A13
|
||||
:0300AE009010258A
|
||||
:0300AF0021003EEF
|
||||
:0300B00003B02B6F
|
||||
:0300B100707C035D
|
||||
:0300B200AB602C14
|
||||
:0300B300209C404E
|
||||
:0300B40013F0390D
|
||||
:0300B500ABE7D9DD
|
||||
:0300B600209AB5D8
|
||||
:0300B70015FC0035
|
||||
:0300B800643208A7
|
||||
:0300B900AE8030E6
|
||||
:0300BA0069B90120
|
||||
:0300BB00AE8C8088
|
||||
:0300BC0020920887
|
||||
:0300BD001BF03005
|
||||
:0300BE00C5090170
|
||||
:0300BF00039C405F
|
||||
:0300C000799039FB
|
||||
:0300C100AC06D9B1
|
||||
:0300C20020BAC69B
|
||||
:0300C300D006F96B
|
||||
:0300C400038BC9E2
|
||||
:0300C500219AC1BC
|
||||
:0300C600E079429C
|
||||
:0300C700348C0274
|
||||
:0300C80034818000
|
||||
:0300C900348E076B
|
||||
:0300CA0034874335
|
||||
:0300CB00030AE73E
|
||||
:0300CC0021AC065E
|
||||
:0300CD00348195E6
|
||||
:0300CE0034874331
|
||||
:0300CF00348AE789
|
||||
:0300D0003487D39F
|
||||
:0300D100D05AE71B
|
||||
:0300D200031C0606
|
||||
:0300D300C00187E2
|
||||
:0300D400032743BC
|
||||
:0300D500033AD813
|
||||
:0300D600C70C0351
|
||||
:0300D700039AE5A4
|
||||
:0300D800C50C074D
|
||||
:0300D90003918709
|
||||
:0300DA00C1874398
|
||||
:0300DB00030ADE37
|
||||
:0300DC00C00C0154
|
||||
:0300DD00031AE51E
|
||||
:0300DE0021BC033F
|
||||
:0300DF0003218773
|
||||
:0300E000C0074313
|
||||
:0300E100033AE4FB
|
||||
:0300E200C70C0048
|
||||
:0300E300039AE598
|
||||
:0300E400C502074B
|
||||
:0300E5000390275E
|
||||
:0300E600C40AF455
|
||||
:0300E700039C0671
|
||||
:0300E800369195B9
|
||||
:0300E900C01643FB
|
||||
:0300EA001FAAF456
|
||||
:0300EB0021CC0124
|
||||
:0300EC0009A1C7A0
|
||||
:0300ED0074309CD0
|
||||
:0300EE00A1E70384
|
||||
:0300EF0003AAF46D
|
||||
:0300F000C02CFF22
|
||||
:0300F100FFF022FB
|
||||
:0300F20016B0271E
|
||||
:0300F300C02B5CC3
|
||||
:0300F40023EC00FA
|
||||
:0300F5007436F36B
|
||||
:0300F60012BCFF3A
|
||||
:0300F70020B02115
|
||||
:0300F800038C0175
|
||||
:0300F900C44024DC
|
||||
:0300FA0003990A5D
|
||||
:0300FB00C406B385
|
||||
:0300FC00039B83E0
|
||||
:0300FD00C00C0133
|
||||
:0300FE0002302F9E
|
||||
:0300FF00ABF2154C
|
||||
:03010000B006D373
|
||||
:03010100000D806E
|
||||
:03010200000024D6
|
||||
:03010300000217E0
|
||||
:03010400000022D6
|
||||
:03010500000C06E5
|
||||
:0301060000019560
|
||||
:03010700000743AB
|
||||
:03010800000B4B9E
|
||||
:030109000006D31A
|
||||
:03010A00000B4B9C
|
||||
:03010B00000CE005
|
||||
:03010C0000015798
|
||||
:03010D00000643A6
|
||||
:03010E00000B4B98
|
||||
:03010F00000C00E1
|
||||
:030110000007B72E
|
||||
:03011100000C05DA
|
||||
:030112000007D70C
|
||||
:03011300000C10CD
|
||||
:030114000007F7EA
|
||||
:03011500000C02D9
|
||||
:03011600000027BF
|
||||
:03011700000C10C9
|
||||
:03011800000D02D5
|
||||
:03011900000FFFD5
|
||||
:03011A000001429F
|
||||
:03011B0000069744
|
||||
:03011C00000D02D1
|
||||
:03011D00000637A2
|
||||
:03011E00000D10C1
|
||||
:03011F00000022BB
|
||||
:03012000000C8050
|
||||
:03012100000124B6
|
||||
:03012200000C02CC
|
||||
:0301230000018058
|
||||
:03012400000E07C3
|
||||
:030125000007438D
|
||||
:03012600000B3992
|
||||
:03012700000C05C4
|
||||
:030128000001478C
|
||||
:030129000006438A
|
||||
:03012A00000B398E
|
||||
:03012B00000C01C4
|
||||
:03012C000001814E
|
||||
:03012D0000074385
|
||||
:03012E00000B3291
|
||||
:03012F00000C10B1
|
||||
:03013000000021AB
|
||||
:03013100000B3987
|
||||
:03013200000C10AE
|
||||
:0301330000018147
|
||||
:030134000007437E
|
||||
:03013500000B3983
|
||||
:03013600000C209A
|
||||
:03013700000021A4
|
||||
:03013800000B3980
|
||||
:03013900000201C0
|
||||
:03013A0000003092
|
||||
:03013B00000901B7
|
||||
:03013C00000204BA
|
||||
:03013D000000308F
|
||||
:03013E00000901B4
|
||||
:03013F00000202B9
|
||||
:030140000000308C
|
||||
:03014100000901B1
|
||||
:03014200000204B4
|
||||
:0301430000003089
|
||||
:03014400000901AE
|
||||
:03014500000202B3
|
||||
:0301460000003086
|
||||
:03014700000901AB
|
||||
:03014800000C8028
|
||||
:03014900000FFFA5
|
||||
:03014A000001644D
|
||||
:03014B00000207A8
|
||||
:03014C000001624D
|
||||
:03014D00000FFFA1
|
||||
:03014E000001505D
|
||||
:03014F00000D0898
|
||||
:0301500000012289
|
||||
:03015100000201A8
|
||||
:03014200000C802E
|
||||
:03014300000FFFAB
|
||||
:0301440000016453
|
||||
:03014500000207AE
|
||||
:0301460000016253
|
||||
:03014700000FFFA7
|
||||
:0301480000015063
|
||||
:03014900000D089E
|
||||
:03014A000001228F
|
||||
:03014B00000201AE
|
||||
:03014C0000003080
|
||||
:03014D00000901A5
|
||||
:03014E00000204A8
|
||||
:03014F000000307D
|
||||
:03015000000901A2
|
||||
:03015100000202A7
|
||||
:030152000000307A
|
||||
:030153000009019F
|
||||
:03015400000204A2
|
||||
:0301550000003077
|
||||
:030156000009019C
|
||||
:03015700000202A1
|
||||
:0301580000003074
|
||||
:0301590000090199
|
||||
:03015A00000C0096
|
||||
:03015B0000002F72
|
||||
:03015C000007D3C6
|
||||
:03015D00000B8410
|
||||
:03015E000002108C
|
||||
:03015F000000227B
|
||||
:0301600000020E8C
|
||||
:0301610000002774
|
||||
:03016200000C503E
|
||||
:0301630000003960
|
||||
:03016400000799F8
|
||||
:03016500000B6428
|
||||
:0301660000021282
|
||||
:0301670000003065
|
||||
:030168000002147E
|
||||
:0301690000003162
|
||||
:03016A000002137D
|
||||
:03016B000006B3D8
|
||||
:03016C00000D1073
|
||||
:03016D000000325D
|
||||
:03016E00000C0082
|
||||
:03016F000000335A
|
||||
:03017000000C7010
|
||||
:0301710000003952
|
||||
:03017200000C502E
|
||||
:0301730000003950
|
||||
:0301740000021571
|
||||
:0301750000003057
|
||||
:030176000002166E
|
||||
:0301770000003154
|
||||
:0301780000020280
|
||||
:0301790000003251
|
||||
:03017A00000C0076
|
||||
:03017B000006B3C8
|
||||
:03017C0000020777
|
||||
:03017D000000334C
|
||||
:03017E00000C7002
|
||||
:03015400000C009C
|
||||
:0301550000002F78
|
||||
:030156000007D3CC
|
||||
:03015700000B7E1C
|
||||
:0301580000021092
|
||||
:0301590000002281
|
||||
:03015A0000020E92
|
||||
:03015B000000277A
|
||||
:03015C00000C5044
|
||||
:03015D0000003966
|
||||
:03015E00000799FE
|
||||
:03015F00000B5E34
|
||||
:0301600000021288
|
||||
:030161000000306B
|
||||
:0301620000021484
|
||||
:0301630000003168
|
||||
:0301640000021383
|
||||
:030165000006B3DE
|
||||
:03016600000D1079
|
||||
:0301670000003263
|
||||
:03016800000C0088
|
||||
:0301690000003360
|
||||
:03016A00000C7016
|
||||
:03016B0000003958
|
||||
:03016C00000C5034
|
||||
:03016D0000003956
|
||||
:03016E0000021577
|
||||
:03016F000000305D
|
||||
:0301700000021674
|
||||
:030171000000315A
|
||||
:0301720000020286
|
||||
:0301730000003257
|
||||
:03017400000C007C
|
||||
:030175000006B3CE
|
||||
:030176000002077D
|
||||
:0301770000003352
|
||||
:03017800000C7008
|
||||
:030179000000394A
|
||||
:03017A00000C5026
|
||||
:03017B0000003948
|
||||
:03017C00000C4034
|
||||
:03017D0000003946
|
||||
:03017E00000C0072
|
||||
:03017F0000003944
|
||||
:03018000000C5020
|
||||
:0301810000003942
|
||||
:03018200000C402E
|
||||
:0301830000003940
|
||||
:03018400000C006C
|
||||
:030185000000393E
|
||||
:03018600000C006A
|
||||
:03018000000C0070
|
||||
:03018100000C006F
|
||||
:03018200000ABFB1
|
||||
:03018300000C026B
|
||||
:0301840000002F49
|
||||
:03018500000C0A61
|
||||
:0301860000002A4C
|
||||
:03018700000C0069
|
||||
:03018800000ABEAC
|
||||
:03018900000C0265
|
||||
:03018A0000002F43
|
||||
:03018B00000C0A5B
|
||||
:03018C0000002A46
|
||||
:03018D00000C0063
|
||||
:03018E000000244A
|
||||
:03018F000007D393
|
||||
:03019000000BACB5
|
||||
:0301910000020168
|
||||
:0301880000002450
|
||||
:030189000007D399
|
||||
:03018A00000BA6C1
|
||||
:03018B000002016E
|
||||
:03018C0000003040
|
||||
:03018D0000090165
|
||||
:03018E0000021557
|
||||
:03018F000000303D
|
||||
:0301900000090162
|
||||
:0301910000021653
|
||||
:030192000000303A
|
||||
:030193000009015F
|
||||
:0301940000021551
|
||||
:0301950000003037
|
||||
:030196000009015C
|
||||
:030197000002164D
|
||||
:03019400000C1F3D
|
||||
:03019500000D80DA
|
||||
:0301960000002244
|
||||
:0301970000020162
|
||||
:0301980000003034
|
||||
:0301990000090159
|
||||
:03019A00000C1F37
|
||||
:03019B00000D80D4
|
||||
:03019C000000223E
|
||||
:03019D000002015C
|
||||
:03019A000002025E
|
||||
:03019B0000003031
|
||||
:03019C0000090156
|
||||
:03019D0000020459
|
||||
:03019E000000302E
|
||||
:03019F0000090153
|
||||
:0301A00000020258
|
||||
:0301A1000000302B
|
||||
:0301A20000090150
|
||||
:0301A30000020453
|
||||
:0301A40000003028
|
||||
:0301A5000009014D
|
||||
:0301A6000002EA6A
|
||||
:0301A7000007103E
|
||||
:0301A800000BAA9F
|
||||
:0301A900000B9DAB
|
||||
:0301AA000007D378
|
||||
:0301AB00000BCA7C
|
||||
:0301AC00000C1D27
|
||||
:0301AD000006D376
|
||||
:0301AE00000D80C1
|
||||
:0301AF000000222B
|
||||
:0301B00000020149
|
||||
:0301A0000002EA70
|
||||
:0301A10000071044
|
||||
:0301A200000BA4AB
|
||||
:0301A300000B97B7
|
||||
:0301A4000007D37E
|
||||
:0301A500000BC488
|
||||
:0301A600000C1D2D
|
||||
:0301A7000006D37C
|
||||
:0301A800000D80C7
|
||||
:0301A90000002231
|
||||
:0301AA000002014F
|
||||
:0301AB0000003021
|
||||
:0301AC0000090146
|
||||
:0301AD000002024B
|
||||
:0301AE000000301E
|
||||
:0301AF0000090143
|
||||
:0301B00000021832
|
||||
:0301B1000000301B
|
||||
:0301B20000090140
|
||||
:0301B30000020245
|
||||
:0301B40000003018
|
||||
:0301B5000009013D
|
||||
:0301B6000002182C
|
||||
:0301B70000003015
|
||||
:0301B8000009013A
|
||||
:0301B90000021031
|
||||
:0301BA0000002E14
|
||||
:0301BB00000C1C19
|
||||
:0301BC000006D367
|
||||
:0301BD00000D80B2
|
||||
:0301BE000000221C
|
||||
:0301BF000002013A
|
||||
:0301B30000021037
|
||||
:0301B40000002E1A
|
||||
:0301B500000C1C1F
|
||||
:0301B6000006D36D
|
||||
:0301B700000D80B8
|
||||
:0301B80000002222
|
||||
:0301B90000020140
|
||||
:0301BA0000003012
|
||||
:0301BB0000090137
|
||||
:0301BC000002023C
|
||||
:0301BD000000300F
|
||||
:0301BE0000090134
|
||||
:0301BF0000021724
|
||||
:0301C0000000300C
|
||||
:0301C10000090131
|
||||
:0301C20000020236
|
||||
:0301C30000003009
|
||||
:0301C4000009012E
|
||||
:0301C5000002171E
|
||||
:0301C60000003006
|
||||
:0301C7000009012B
|
||||
:0301C8000007D35A
|
||||
:0301C900000B9197
|
||||
:0301CA00000C0026
|
||||
:0301CB0000002F02
|
||||
:0301CC000007D356
|
||||
:0301CD00000B84A0
|
||||
:0301CE00000B5EC5
|
||||
:0301CF00000C071A
|
||||
:0301D00000002FFD
|
||||
:0301D100000C041B
|
||||
:0301D20000002109
|
||||
:0301D300000C001D
|
||||
:0301D40000091E01
|
||||
:0301C2000007D360
|
||||
:0301C300000B8BA3
|
||||
:0301C400000C002C
|
||||
:0301C50000002F08
|
||||
:0301C6000007D35C
|
||||
:0301C700000B7EAC
|
||||
:0301C800000B58D1
|
||||
:0301C900000C0720
|
||||
:0301CA0000002F03
|
||||
:0301CB00000C0421
|
||||
:0301CC000000210F
|
||||
:0301CD00000C0023
|
||||
:0301CE0000091E07
|
||||
:0301CF00000C1011
|
||||
:0301D0000000210B
|
||||
:0301D100000C0817
|
||||
:0301D20000091E03
|
||||
:0301D300000C40DD
|
||||
:0301D40000002107
|
||||
:0301D500000C100B
|
||||
:0301D60000002105
|
||||
:0301D700000C0811
|
||||
:0301D80000091EFD
|
||||
:0301D900000C40D7
|
||||
:0301DA0000002101
|
||||
:0301DB00000C1005
|
||||
:0301DC0000091EF9
|
||||
:0301DD00000C0013
|
||||
:0301DE00000026F8
|
||||
:0301DF00000C0110
|
||||
:0301E000000029F3
|
||||
:0301E100000C000F
|
||||
:0301E20000002FEB
|
||||
:0301E300000C20ED
|
||||
:0301E400000023F5
|
||||
:0301E500000A000D
|
||||
:0301E600000ABE4E
|
||||
:0301E700000BE723
|
||||
:0301D60000091EFF
|
||||
:0301D700000C0019
|
||||
:0301D80000003AEA
|
||||
:0301D900000C0116
|
||||
:0301DA00000029F9
|
||||
:0301DB00000C0015
|
||||
:0301DC0000002FF1
|
||||
:0301DD00000C20F3
|
||||
:0301DE00000023FB
|
||||
:0301DF00000A0013
|
||||
:0301E000000ABF53
|
||||
:0301E100000BE12F
|
||||
:00000001FF
|
||||
|
||||
578
drivers/dahdi/xpp/firmwares/USB_FW.201.hex
Normal file
578
drivers/dahdi/xpp/firmwares/USB_FW.201.hex
Normal file
@@ -0,0 +1,578 @@
|
||||
#
|
||||
# $Id: USB_FW.201.hex 10402 2012-02-15 15:34:50Z dima $
|
||||
#
|
||||
:03004300021F0099
|
||||
:03005300021F0089
|
||||
:101F0000021E3100021E8E00021E7800021E4900D1
|
||||
:081F1000021C2000021BA900C5
|
||||
:101000001201000200000040AAAAAAAAAAAA01028C
|
||||
:1010100003010A0600020000004001000902370037
|
||||
:10102000020100C0000904000002FFFFFF040705E1
|
||||
:101030000202000200070586020002000904010006
|
||||
:1010400002FFFFFF050705040200020007058802F2
|
||||
:10105000000200001201000200000040E4E451110F
|
||||
:101060000000010203010A06000200000040010026
|
||||
:1010700009023700020100C0320904000002FFFF2C
|
||||
:10108000FF04070502024000000705860240000039
|
||||
:101090000904010002FFFFFF0507050402400000EC
|
||||
:1010A0000705880240000006040016001400120024
|
||||
:1010B0000A00260004030904160358006F0072009A
|
||||
:1010C00063006F006D0020004C00540044001403C6
|
||||
:1010D00041007300740072006900620061006E00DC
|
||||
:1010E0006B001203530065007200690061006C0020
|
||||
:1010F0004E006F000A0346005000470041002603DF
|
||||
:101100004D0061006E00610067006D0065006E00BB
|
||||
:101110007400500072006F0063006500730073007C
|
||||
:061120006F0072000000E8
|
||||
:050FF6000300000000F3
|
||||
:100F3C0041E0370041E0B60042E0B1000041E0384A
|
||||
:100F4C0000021BE0850218E07943E0B30000004D7D
|
||||
:0F0F5C00E03931303339354D202020202020005E
|
||||
:101D71008B538A548955E5581558AE57700215573B
|
||||
:101D81004E6014AB530555E555AA54700205541421
|
||||
:081D9100F9ED12077780DF2253
|
||||
:101BE6008B538A548955E55A155AAE5970021559C0
|
||||
:101BF6004E6026AB560558E558AA5770020557148D
|
||||
:101C0600F9120731FFAB530555E555AA5470020585
|
||||
:0A1C16005414F9EF12077780CD2275
|
||||
:101DC100D2B7E490E670F0F5B575B5E653B5E743E3
|
||||
:101DD100B28853B2FCC2B3D2B1C2B2C2B67F32FE34
|
||||
:061DE100121E07D2B6221B
|
||||
:101E6100538EF75389FB5389F74389015389FDE465
|
||||
:071E7100F58AF58CD2A922CD
|
||||
:1018B2008C448D45AA06A9077556018A5789587521
|
||||
:1018C2005900755A1C7B017AE0794C121BE690E0B4
|
||||
:1018D20064E0FCA3E0FDA3E0FEA3E064D1FFEE64BC
|
||||
:1018E2008DFEED644CFDEC6449FC90E064120853FB
|
||||
:1018F2007EE07F4C7D1C7C001213707EE07F4C7B6F
|
||||
:101902001C7A00AD45AC441214247D1C7C00AF450A
|
||||
:10191200AE441211F57D1C7C00AF45AE44021C564C
|
||||
:08183F008E448F458C468D4755
|
||||
:10184700C20712001290E15BEFF0BF5004D207808D
|
||||
:1018570057E490E15CF0A3F090E15CE0FEA3E0FFC9
|
||||
:10186700C39410EE648094805030E5472FF582E5ED
|
||||
:10187700463EF583E0FF90E15CE0FCA3E02545F5FB
|
||||
:1018870082E5443CF583E0B5071090E15DE004F0A4
|
||||
:1018970070C690E15CE004F080BE90E15CE070040B
|
||||
:0A18A700A3E064107002D207A2074C
|
||||
:0118B1002214
|
||||
:020E12008F410E
|
||||
:100E14001200128F42E4F546F547AD47AC46121472
|
||||
:100E2400DA74692547F582E434E0F583E543F00597
|
||||
:100E340047E54770020546C39408E54664809480FC
|
||||
:100E440040D8E541600490E069F090E069E0B4C006
|
||||
:100E540008754400754508800675441D754536754A
|
||||
:100E64004600754708C3E5479410E54664809480BE
|
||||
:100E740050231214D674692547F582E434E0F583CF
|
||||
:100E8400E543F00547E547700205460545E545702D
|
||||
:100E9400D4054480D07543FF75441D7545197546C6
|
||||
:100EA40000754710C3E547942CE546648094805050
|
||||
:100EB40033E542B4510E7B007A007943AD45AC442E
|
||||
:100EC400FF1214E274692547F582E434E0F583E502
|
||||
:100ED40043F00547E547700205460545E54570C4FE
|
||||
:100EE400054480C075441D75453EE4F543F546F55B
|
||||
:100EF40047C3E5479406E54664809480502FE54255
|
||||
:100F0400B4510A90E069E0B4C2031214D6744625C1
|
||||
:100F140047F582E434E0F583E543F00547E547709F
|
||||
:100F24000205460545E54570C8054480C490E0695E
|
||||
:070F3400E0B4C20374C0F039
|
||||
:010F3B002293
|
||||
:0A1988008E448F458B468A4789483C
|
||||
:101992007E00E5452DF54DEE3544F54C1200128FD3
|
||||
:1019A20049E5496451600BC3E5459410E544940050
|
||||
:1019B200503585444A85454BC3E54B954DE54A95DF
|
||||
:1019C2004C5024AB46AA47A948AD4BAC4AAF49128A
|
||||
:1019D2001740054BE54B7002054A74012548F5484E
|
||||
:0719E200E43547F54780D111
|
||||
:0119E90022DB
|
||||
:0617C7008B418A428943B8
|
||||
:1017CD00D2067556017557E0755869755900755AE9
|
||||
:1017DD00107B017AE07995121BE6E5432410F9E4BC
|
||||
:1017ED003542854156F5578958755900755A0C7B08
|
||||
:1017FD00017AE079A5121BE67EE07F957CE07D1AEB
|
||||
:10180D001218B27EE07F1AE543241CF9E43542FC40
|
||||
:10181D00AD0112183F5016AB41E5432410F9E435E4
|
||||
:10182D0042FA7D1C7F197E1D1219888002C206A204
|
||||
:01183D0006A4
|
||||
:01183E002287
|
||||
:101126007F03121D46EF2402FFE43EA90775410125
|
||||
:10113600F542894390E06AE0FFE50C2408F582E475
|
||||
:10114600350BF583EFF090E06BE0FFE50C2409F535
|
||||
:1011560082E4350BF583EFF090E06CE0FFE50C24BC
|
||||
:101166000AF582E4350BF583EFF090E06DE0FFE5DC
|
||||
:101176000C240BF582E4350BF583EFF090E06EE07E
|
||||
:10118600FFE50C240CF582E4350BF583EFF090E0D7
|
||||
:101196006FE0FFE50C240DF582E4350BF583EFF0E7
|
||||
:1011A6007F087E00E4FDEDC39408502874692FF58E
|
||||
:1011B60082E434E0F583E0FCAB41AA42A94375F032
|
||||
:1011C60002EDA4F58285F083EC1207890D0FBF00AE
|
||||
:1011D600010E80D2E5192404F582E43518F583E082
|
||||
:0E11E60030E0047F0180027F0090E037EFF0E0
|
||||
:0111F40022D8
|
||||
:101B250090E06CE02FFFE50C240AF582E4350BF517
|
||||
:101B350083EFF0E50C240BF582E4350BF583E0FE2D
|
||||
:101B4500E50C240AF582E4350BF583E0FDEDFF9005
|
||||
:101B5500E0B1EEF0A3EFF0D206121CBD90E680E0F6
|
||||
:041B650054F7F0221F
|
||||
:1016200090E600E054E74410F090E60174C0F090BA
|
||||
:10163000E6107420F000000090E611F00000009029
|
||||
:10164000E6047480F0000000740FF0000000E4F085
|
||||
:1016500000000090E6187410F0000000E490E61915
|
||||
:10166000F000000090E61A7408F0000000E490E634
|
||||
:101670001BF000000090E6497482F0000000F000CA
|
||||
:10168000000090E6247402F0000000E490E625F0EB
|
||||
:1016900000000090E6957480F0000000F00000006B
|
||||
:1016A00043AF017B017AE07914755700755806E461
|
||||
:0416B000FD021D71A9
|
||||
:061E0100D2837F0A7E007F
|
||||
:101E07007C007D181207ABEF1FAC0670011E4C70EB
|
||||
:021E1700F622B1
|
||||
:0A1A43008E418F428B438A4489458F
|
||||
:101A4D00E4F546F547C3E5479542E54695415036E1
|
||||
:101A5D00AB43AA44A94585478285468312074AFFB1
|
||||
:101A6D00E4FBFAC2B2EF1392B1EFC313FFD2B20B84
|
||||
:101A7D00BB00010AEB64084A70E9C2B20547E547AD
|
||||
:071A8D0070C3054680BFD3C2
|
||||
:011A9400222F
|
||||
:101E190090E60174C0F0C2B67FC27E01121E07D2DD
|
||||
:081E2900B67F327E00021E07A5
|
||||
:101EA400D287121E01C287121E03C2837F0A7E00DC
|
||||
:031EB400021E0704
|
||||
:021B6900AB07C8
|
||||
:101B6B00E4F9FAEBC413131354011392877F027E2B
|
||||
:101B7B0000121E07D2837F057E00121E07E925E0A7
|
||||
:101B8B00FFA2B3E4334FF97F057E00121E07EB254E
|
||||
:0D1B9B00E0FBC283121E030ABA08C8AF01A6
|
||||
:011BA800221A
|
||||
:061A95008B558A568957AB
|
||||
:101A9B00A2AFE433F55D121EA4E4F55CE55CC395DF
|
||||
:101AAB005B5027AB55AA56A957855C8275830012EC
|
||||
:101ABB00074AFF121B69AB58AA59A95A855C827554
|
||||
:101ACB008300EF120789055C80D2120036E55D2496
|
||||
:031ADB00FF92AFC8
|
||||
:011ADE0022E5
|
||||
:0B003600C287121E03121E01D2872297
|
||||
:101DE70075418F8F42755800755900755A4B755B51
|
||||
:0A1DF700027B007A007941021A9580
|
||||
:101C8C0078417C007D007BFF7A0F79F67E007F0522
|
||||
:101C9C0012070B30B415755800755900755A4175FB
|
||||
:101CAC005B057B007A007941121A95E5435401FFDC
|
||||
:011CBC002205
|
||||
:100B4E007541007542007543007545017546E075A7
|
||||
:100B5E0047007548017549E0754A08E4F551FFF5FF
|
||||
:100B6E00527B017AE07900F557755808FD121D7118
|
||||
:100B7E00AB45AA46A9477401120777E4F550E55034
|
||||
:100B8E00C454F0AB45AA46A94790000112078985C7
|
||||
:100B9E004858854959854A5A755B08121A95AB48CB
|
||||
:100BAE00AA49A94A90000212074AFE5403FFEE54C6
|
||||
:100BBE0070F55124E0602924F0604B24F0605D2430
|
||||
:100BCE00F0606F24406003020C5675410185184297
|
||||
:100BDE00851943EF24FE600624FE703B801C801FA7
|
||||
:100BEE00E5192401FDE43518A905754101F5428981
|
||||
:100BFE0043EF24FC60092402700A7552028052757C
|
||||
:100C0E005206804D8011E5192402FDE43518A90520
|
||||
:100C1E00754101F54289437552088035E519240363
|
||||
:100C2E00FDE43518A905754101F542894375520455
|
||||
:100C3E00801FE5192405FDE43518A905754101F558
|
||||
:100C4E00428943755298800975410075420075437B
|
||||
:100C5E0000E542454345416022AB41AA42A94312F9
|
||||
:100C6E000731FED395524006AD52AE0580008E443C
|
||||
:100C7E00120731C39544120777800CE55170047E3C
|
||||
:100C8E000180027E008E44744B2550F8A644055018
|
||||
:100C9E00E550C394055003020B8CAB45AA46A947F9
|
||||
:100CAE007488120777AB45E5472401F9E43546FA17
|
||||
:100CBE0075560075570075584B755900755A0512C3
|
||||
:100CCE001BE6854858854959854A5A755B08AB45D8
|
||||
:070CDE00AA46A947021A957E
|
||||
:1019EA008F4190E0B1E0FEA3E054F064607003EE32
|
||||
:1019FA00641160037F012290E037E070037F0F22B9
|
||||
:101A0A00E5417003308108E541B401062080037F77
|
||||
:101A1A00102290E0B6E0B541037F0122E4F511D22D
|
||||
:101A2A0006121CBDAF4190E0B6EFF024FF92B590CC
|
||||
:091A3A00E680E054F7F07F002281
|
||||
:04000E0090FC04F06E
|
||||
:1000120090E678E0541824F06008240870087F50B5
|
||||
:0800220080067F518002E4FF1B
|
||||
:01002A0022B3
|
||||
:0C14D600AD45AC447B007A007943AF4286
|
||||
:0C14E2008F488C498D4A8B4B8A4C894DF9
|
||||
:1014EE00E4F54EF54F755003FDF551F552A2AF33AD
|
||||
:1014FE00F553E54824AF600D047012754E00754F1C
|
||||
:10150E00017D018008754E00754F02E4FDE54860CF
|
||||
:10151E0051E54F454E604BE54990E0B3F0E54AA3E7
|
||||
:10152E00F074B32DF582E434E0AD82FCAB4FAF48DE
|
||||
:10153E001219227551008F527F0A7E00121ADFE5B2
|
||||
:10154E0052455160107CE07D687B01AF4812157BDF
|
||||
:10155E007551008F5290E068E0AB4BAA4CA94D122A
|
||||
:0C156E000777E55324FF92AFAE51AF5257
|
||||
:01157A00224E
|
||||
:0C1740008F4E8C4F8D508B518A52895374
|
||||
:10174C00E4F554F555755603FDF557F558A2AF332E
|
||||
:10175C00F559E54E24AF600D0470127554007555A3
|
||||
:10176C00027D018008755400755503E4FDE54E605B
|
||||
:10177C003FE55545546039E54F90E0B3F0E550A393
|
||||
:10178C00F0AB51AA52A95312073190E0B5F0C2B791
|
||||
:10179C0074B32DF582E434E0AD82FCAB55AF4E1240
|
||||
:1017AC0019227557008F587F0A7E00121ADFD2B7A4
|
||||
:0A17BC00E55924FF92AFAE57AF5875
|
||||
:0117C6002200
|
||||
:10005600E4F531F532F535F53CF53DF53EF53FE590
|
||||
:10006600AA5484600302063A90E694E0FE90E69570
|
||||
:10007600E0FBEEF53CEBF53DC39405E53C94004012
|
||||
:100086000790F404E0FD80027DFFED12085F00CECC
|
||||
:100096000102C30503080703580903D80B011E0E06
|
||||
:1000A60000E40F019411025E130541250401310499
|
||||
:1000B6005732046A3404B23504C93604E63703E518
|
||||
:1000C6004503F647000005BA75310075320790FC06
|
||||
:1000D600047481F0A37414F0E4A3F00205DD7F0F2D
|
||||
:1000E600121DE775310075320690FC047480F0E449
|
||||
:1000F600A3F0753505F511FE74002535F9EE34F4D7
|
||||
:10010600FA7B011217C7400690FC05740EF0E4FF57
|
||||
:10011600120E127F8F0202BD7F0E121DE77531008F
|
||||
:10012600753205748E12000E8F3F7B007A0079407F
|
||||
:10013600E4FDFC1214E2E53F64516019E53F6450AA
|
||||
:10014600601375310075320690FC047480F0A37458
|
||||
:100156000BF00205DD90E0B7E0FF120E12740025E9
|
||||
:1001660032F974FC3531FA7B01C0038B567557E0C2
|
||||
:10017600755869755900755A2CD003121BE6742CF4
|
||||
:100186002532F532E43531F5317F8E0202BD753107
|
||||
:100196000075320790FC047491F090E678E090FCCC
|
||||
:1001A60005F030B3047F0280027F0030B4047E0184
|
||||
:1001B60080027E00EE4F90FC06F074002532F97442
|
||||
:1001C600FC3531FA7B01755700755812E4FD121D96
|
||||
:1001D6007174002532F974FC3531FA7B01C0038B4A
|
||||
:1001E600567557E0755839755900755A06D0031279
|
||||
:1001F6001BE674062532F532E43531F531FE74001E
|
||||
:100206002532F974FC3EFA7B01C0038B567557E024
|
||||
:10021600755814755900755A06D003121BE67406F4
|
||||
:100226002532F532E43531F531FE74002532F974A4
|
||||
:10023600FC3EFA7B01C0038B567557E07558467530
|
||||
:100246005900755A06D003121BE674062532F5329C
|
||||
:10025600E43531F5310205DD7F13121DE7753100F6
|
||||
:1002660075321D749312000E8F3F75381D75390057
|
||||
:10027600753600753705D3E5399418E538941D5061
|
||||
:1002860034E53FB4510E7B007A007940AD39AC3885
|
||||
:10029600FF1214E274002537F58274FC3536F583B7
|
||||
:1002A600E540F00539E539700205380537E5377060
|
||||
:1002B600C5053680C17F93121DE70205DD75310045
|
||||
:1002C60075320690FC047480F0E4A3F090F405E027
|
||||
:1002D60090E038F0E0147071121E1930B31B755699
|
||||
:1002E600017557F4755806755900755A067B017ADB
|
||||
:1002F600E07914121BE60205DD90FC057401F0029C
|
||||
:1003060003D075310075320690FC047480F0E4A3C6
|
||||
:10031600F0753507AF35FEC3E53D9FF534E53C9EE8
|
||||
:10032600F53390E038E014702074002FF974F43E31
|
||||
:10033600FA7B01AF34AE33121A435004E40204C20E
|
||||
:1003460090FC05740CF00205DD90FC057403F002C8
|
||||
:1003560005DD75310075320690FC047480F0E4A367
|
||||
:10036600F090E038E014705CE4FFFE20B411C2B2F5
|
||||
:10037600D2B1D2B20FBF00010EEF640A4E70EC305C
|
||||
:10038600B43A90E6017403F07F647E00121E079073
|
||||
:10039600E0B7E0FF120E127EE07F697CE07DB812C6
|
||||
:1003A60018B27EE07FB8AD1CAC1B12183F50051288
|
||||
:1003B6000B4E801690FC05740EF0800E90FC0574B2
|
||||
:1003C6000DF0800690FC057403F0E490E038F0022E
|
||||
:1003D60005DDE4F531F5327F02121B250205DDE469
|
||||
:1003E600FF120E12121126E4FF1219EAE4FF800230
|
||||
:1003F6007F01121B25121E190205DD7531007532AB
|
||||
:100406000690FC047480F0E4A3F090F405E0F53E59
|
||||
:10041600E4F511E53E64016004E53E703290E0B11A
|
||||
:10042600E0FEA3E054F064607003EE6411600280A5
|
||||
:100436007290E037E070028058E5116401600AE5C9
|
||||
:1004460011700C121C8CEF6006853E110205DD80D2
|
||||
:100456005275310075320690FC0474B2F0A3E511B2
|
||||
:10046600F00205DD75310075320690FC047480F0EB
|
||||
:10047600E4A3F090F405E0F53EFF1219EAEF24F14B
|
||||
:10048600600F1460152410701AE4F531F532020578
|
||||
:10049600DD90FC05740FF00205DD90FC057410F08C
|
||||
:1004A6000205DD90FC057401F00205DD753100756D
|
||||
:1004B600320690FC0474B5F090E0B6E090FC05F0CE
|
||||
:1004C6000205DD75310075320690FC0474B6F0A2A3
|
||||
:1004D60080E43325E0FFA281E4334FA3F00205DD7B
|
||||
:1004E600853C31853D3290FC0474B7F0753505C303
|
||||
:1004F600E53D9535F534E53C9400F5337400253536
|
||||
:10050600F582E434F4F583E0648870030205DDAF18
|
||||
:10051600357E0074002FF9EE34F4FA7B01C003C077
|
||||
:100526000174002FF9EE34FC8B58F559895A85343D
|
||||
:100536005BD001D003121A950205DD7531007532C4
|
||||
:100546000590FC0474A5F01200128F3F7B007A0020
|
||||
:100556007940E4FDFC1214E290E036E0FF0532E556
|
||||
:1005660032AC3170020531142400F58274FC3CF57E
|
||||
:1005760083EFF090E0B7E0FF0532E532AC31700270
|
||||
:100586000531142400F58274FC3CF583EFF0053246
|
||||
:10059600E532AE3170020531142400F58274FC3E5A
|
||||
:1005A600F583E540F090E6017403F07F647E001267
|
||||
:1005B6001E07802375310075320690FC047480F0A6
|
||||
:1005C600C3E53D9405E53C94005006A37407F0800E
|
||||
:1005D6000690FC057406F090F404E0B48004A3E0F1
|
||||
:1005E600701290F404E06405600FE06407600AE0AE
|
||||
:1005F60064096005E490E038F0E5324531602CE5A9
|
||||
:1006060032FD90FC00F0E531FFA3F090F402E0909B
|
||||
:10061600FC02F090F403E090FC03F090E69CEFF00F
|
||||
:1006260000000090E69DEDF000000090E6957480D5
|
||||
:04063600F0000000D0
|
||||
:01063A00229D
|
||||
:02004100D322C8
|
||||
:0800030090E6BAE0F51DD322DE
|
||||
:101ECA0090E740E51DF0E490E68AF090E68B04F096
|
||||
:021EDA00D32211
|
||||
:08002B0090E6BAE0F51AD322B9
|
||||
:101EDC0090E740E51AF0E490E68AF090E68B04F087
|
||||
:021EEC00D322FF
|
||||
:101D990090E6B9E0242F600D04701990E604E0FF85
|
||||
:101DA900430780800890E604E0FF53077F000000A6
|
||||
:071DB900EFF08002D322C30A
|
||||
:011DC0002200
|
||||
:101E3100C0E0C083C082D2015391EF90E65D74018E
|
||||
:081E4100F0D082D083D0E03222
|
||||
:101E7800C0E0C083C0825391EF90E65D7404F0D057
|
||||
:061E880082D083D0E0329D
|
||||
:101E8E00C0E0C083C0825391EF90E65D7402F0D043
|
||||
:061E9E0082D083D0E03287
|
||||
:101C2000C0E0C083C08285120D85130E850E8285AB
|
||||
:101C30000D83A37402F085090F850A108510828533
|
||||
:101C40000F83A37407F05391EF90E65D7410F0D00A
|
||||
:061C500082D083D0E032D7
|
||||
:101E4900C0E0C083C082D2035391EF90E65D74086D
|
||||
:081E5900F0D082D083D0E0320A
|
||||
:101BA900C0E0C083C08290E680E030E72085090D5F
|
||||
:101BB900850A0E850E82850D83A37402F085120FA6
|
||||
:101BC900851310851082850F83A37407F05391EF55
|
||||
:0D1BD90090E65D7420F0D082D083D0E03221
|
||||
:101EB700000102020303040405050300000000C03B
|
||||
:031EC700C2000056
|
||||
:060F6B0001110001080065
|
||||
:03000B000212BC22
|
||||
:1012BC00C0E0C0F0C083C082C0D075D000C000C0F8
|
||||
:0D12CC0001C002C003C004C005C006C00779
|
||||
:1012D90078217C007D007BFF7A1E79C17E007F0525
|
||||
:1012E90012070B90E0B6E0F526C204752700E50861
|
||||
:1012F900600415088056750805E5117004C204805C
|
||||
:1013090043A280308101B3500B3081047F008030CB
|
||||
:101319007F01802C30B415755800755900755A2114
|
||||
:10132900755B057B007A007921121A95E523540132
|
||||
:10133900F527701090E0B6E060047F0080027F011D
|
||||
:0C1349008F26D204300405AF261219EAEA
|
||||
:10135500D007D006D005D004D003D002D001D000EC
|
||||
:0B136500D0D0D082D083D0F0D0E03296
|
||||
:100CE50078567CE17D017BFF7A1E79C67E007F0404
|
||||
:100CF50012070BC203C200D202C201121DC1121E8D
|
||||
:100D050061121620750B10750C00751410751512EF
|
||||
:100D1500750910750A1C75121075137085120F85EB
|
||||
:100D250013107516107517B412001290E154EFF0F8
|
||||
:100D35007B017AE17955E4FDFC1214E290E155E07E
|
||||
:100D4500FF90E036F0E490E0B7F0EF64C26059EF51
|
||||
:100D550064C06054E490E15AF090E15AE0FFC39416
|
||||
:100D650004504A74562FF582E434E1F583E0FF60C0
|
||||
:100D75003C120E127EE07F697CE07DB81218B27ECF
|
||||
:100D8500E07FB8AD1CAC1B12183F501490E15AE03F
|
||||
:100D95002456F582E434E1F583E090E0B7F0800D68
|
||||
:100DA50090E15AE004F080B1E4FF120E1212112610
|
||||
:100DB500D2E843D82090E668E04409F090E65CE08C
|
||||
:100DC500443DF012001290E154EFF07B017AE17995
|
||||
:100DD50055E4FDFC1214E290E155E064C26007E4BD
|
||||
:100DE50090E0B6F0C2B57F01121B25D2AFD28C536D
|
||||
:100DF5008EF8C203C2AF120056D2AF3001051209F8
|
||||
:0D0E050026C2013003EEC203121D1A80E761
|
||||
:0B00460090E50DE030E402C322D3225D
|
||||
:1009260090E6B9E070030209EB147003020A602432
|
||||
:10093600FE7003020ADB24FB70030209E514700350
|
||||
:100946000209DF1470030209D31470030209D924C3
|
||||
:10095600056003020B3A1200414003020B4690E683
|
||||
:10096600BBE024FE602714603E24FD60111460275E
|
||||
:1009760024067056E50B90E6B3F0E50C80421200B3
|
||||
:10098600465044E51490E6B3F0E5158033E50D9046
|
||||
:10099600E6B3F0E50E802985120F851310E50F905A
|
||||
:1009A600E6B3F0E510801990E6BAE0FF121D46AAFC
|
||||
:1009B60006A9077B01EA494B600DEE90E6B3F0EF1E
|
||||
:1009C60090E6B4F0020B46020B35020B35121EDC24
|
||||
:1009D600020B4612002B020B46120003020B4612B4
|
||||
:1009E6001ECA020B4690E6B8E0247F601514601913
|
||||
:1009F60024027063A200E43325E0FFA202E4334F31
|
||||
:100A06008041E490E740F0803F90E6BCE0547EFFF2
|
||||
:100A16007E00E0D394807C0040047D0180027D004E
|
||||
:100A2600EC4EFEED4F24B7F582741E3EF583E4933B
|
||||
:100A3600FF3395E0FEEF24A1FFEE34E68F82F583C7
|
||||
:100A4600E0540190E740F0E4A3F090E68AF090E6E7
|
||||
:100A56008B7402F0020B46020B3590E6B8E024FEDA
|
||||
:100A6600601624026003020B4690E6BAE0B4010564
|
||||
:100A7600C200020B46020B3590E6BAE0705590E6CE
|
||||
:100A8600BCE0547EFF7E00E0D394807C0040047D71
|
||||
:100A96000180027D00EC4EFEED4F24B7F582741EF8
|
||||
:100AA6003EF583E493FF3395E0FEEF24A1FFEE3499
|
||||
:100AB600E68F82F583E054FEF090E6BCE0548013A6
|
||||
:100AC6001313541FFFE0540F2F90E683F0E04420E9
|
||||
:100AD600F0806D805A90E6B8E024FE60192402701A
|
||||
:100AE6004E90E6BAE0B40104D200805490E6BAE033
|
||||
:100AF6006402604C803990E6BCE0547EFF7E00E0E4
|
||||
:100B0600D394807C0040047D0180027D00EC4EFE83
|
||||
:100B1600ED4F24B7F582741E3EF583E493FF3395BB
|
||||
:100B2600E0FEEF24A1FFEE34E68F82F583800D9080
|
||||
:100B3600E6A08008121D99500790E6A0E04401F057
|
||||
:070B460090E6A0E04480F0FE
|
||||
:010B4D002285
|
||||
:03003300020FFBBE
|
||||
:040FFB0053D8EF32A6
|
||||
:100F71006080E0D4292E43C9A2D87C013D3654A11A
|
||||
:100F8100ECF0061362A705F3C0C7738C98932BD9B5
|
||||
:100F9100BC4C82CA1E9B573CFDD4E01667426F18B9
|
||||
:100FA1008A17E512BE4EC4D6DA9EDE49A0FBF58E45
|
||||
:100FB100BB2FEE7AA968799115B2073F94C21089C7
|
||||
:100FC1000B225F21807F5D9A5A903227353ECCE714
|
||||
:100FD100BFF79703FF1930B348A5B5D1D75E922A61
|
||||
:100FE100AC56AAC64FB838D296A47DB676FC6BE251
|
||||
:040FF1009C7404F1F7
|
||||
:081370008C468D47AB07AA066D
|
||||
:10137800E4F548F549C3E5499547E5466480F8E54D
|
||||
:1013880048648098400302141FE54925E0FFE548BA
|
||||
:1013980033FE74D42FF58274E03EF583E0FF7E00BF
|
||||
:1013A800AC46AD471207BD8C4A8D4BE54925E0FF99
|
||||
:1013B800E54833FE74D52FF58274E03EF583E0FFEF
|
||||
:1013C8007E00AC46AD471207BD8C4C8D4DE54B6594
|
||||
:1013D8004D7004E54A654C6030EB254BF582EA35E3
|
||||
:1013E8004AF583E0F9EB254DF582EA354CF583E0C3
|
||||
:1013F800FFEB254BF582EA354AF583EFF0EB254DF7
|
||||
:10140800F582EA354CF583E9F00549E549600302C0
|
||||
:0B141800137D054802137D7E007F015C
|
||||
:0114230022A6
|
||||
:0C1424008E468F478C488D498A4A8B4BBE
|
||||
:10143000E54745466006E54945487004E4FEFF225D
|
||||
:10144000E4F54CF54DC3E54D954BE54A6480F8E570
|
||||
:101450004C648098507BE4F54EF54FE549254DF5F9
|
||||
:1014600082E548354CF583E4F0C3E54F954BE54AFA
|
||||
:101470006480F8E54E6480985049E54F254D24D4AA
|
||||
:10148000F582E434E0F583E0FFE547254FF582E59A
|
||||
:1014900046354EF583E0FEEF8EF0A4FFE549254D7D
|
||||
:1014A000F582E548354CF583E02FFFE549254DF5FC
|
||||
:1014B00082E548354CF583EFF0054FE54F70AA05FE
|
||||
:1014C0004E80A6054DE54D6003021445054C0214FF
|
||||
:0514D000457E007F01D4
|
||||
:0114D50022F4
|
||||
:101CEC00120731FF90000312074A12077790000386
|
||||
:101CFC00EF12078990000212074AFF9000011207A9
|
||||
:0E1D0C004A900002120789900001EF02078939
|
||||
:0811F5008E468F478C488D499E
|
||||
:1011FD00E4F54AF54BE549AE487802CEA2E713CEA9
|
||||
:10120D0013D8F8FFC3E54B9FEE6480F8E54A648080
|
||||
:10121D009840030212B7E54BAE4A7802C333CE3382
|
||||
:10122D00CED8F92547FFEE3546FAA9077B018B4C41
|
||||
:10123D00F54D894E74D5254BF582E434E0F583E008
|
||||
:10124D00541FFFE48F52F551F550F54F121CECABC6
|
||||
:10125D004CAA4DA94E120819C374209552F9F812D3
|
||||
:10126D000806C004C005C006C007A94E120819A97A
|
||||
:10127D0052A8011207F3D003D002D001D000EF4BDA
|
||||
:10128D00FFEE4AFEED49FDEC48FCAB4CAA4DA94ED4
|
||||
:10129D00120839AB4CAA4DA94E121CEC054BE54B6F
|
||||
:0E12AD006003021202054A0212027E007F0157
|
||||
:0112BB002210
|
||||
:101C5600D3ED9410EC64809480402AED1D70011C35
|
||||
:101C6600142FF582EE3CF583E0FB547F24D4F582F5
|
||||
:101C7600E434E0F583E0F9540F2FF582E43EF58372
|
||||
:051C8600E06BF080CBD3
|
||||
:011C8B002236
|
||||
:101D1A0090E682E030E004E020E60B90E682E030D4
|
||||
:101D2A00E119E030E71590E680E04401F07F147E87
|
||||
:0C1D3A0000121ADF90E680E054FEF02258
|
||||
:101CBD0030060990E680E0440AF0800790E680E067
|
||||
:101CCD004408F07FDC7E05121ADF90E65D74FFF0AC
|
||||
:0F1CDD0090E65FF05391EF90E680E054F7F0222D
|
||||
:101ADF008E5A8F5B90E600E054187012E55B24017C
|
||||
:101AEF00FFE4355AC313F55AEF13F55B801590E6F3
|
||||
:101AFF0000E05418FFBF100BE55B25E0F55BE55ADE
|
||||
:101B0F0033F55AE55B155BAE5A7002155A4E6005F8
|
||||
:061B1F00121EEE80EE2212
|
||||
:06157B008C548D55AE07F3
|
||||
:10158100EB70037F012290E678E020E6F990E6789F
|
||||
:101591007480F0EE25E0440190E679F090E678E081
|
||||
:1015A10030E0F990E678E020E26BE030E167BB01E2
|
||||
:1015B1000790E678E04420F090E679E0F5561BEBE1
|
||||
:1015C100603090E678E030E0F990E678E020E2459E
|
||||
:1015D100BB010790E678E04420F090E679E0FF0552
|
||||
:1015E10055E555AC547002055414F5828C83EFF027
|
||||
:1015F10080CC90E678E030E0F990E678E020E215E2
|
||||
:1016010090E678E04440F090E679E0855582855493
|
||||
:0E16110083F07F012290E678E04440F07F00F5
|
||||
:01161F0022A8
|
||||
:1019220090E678E020E6F990E6787480F0EF25E022
|
||||
:1019320090E679F090E678E030E0F990E678E02001
|
||||
:10194200E23AE030E136EBD3940040260DEDAE04EE
|
||||
:1019520070010C14F5828E83E090E679F01B90E61C
|
||||
:1019620078E030E0F990E678E020E210E020E1D67D
|
||||
:10197200800A90E678E04440F07F012290E678E029
|
||||
:051982004440F07F006D
|
||||
:01198700223D
|
||||
:021D4600A907EB
|
||||
:101D4800AE16AF178F828E83A3E064037017AD01C0
|
||||
:101D580019ED7001228F828E83E07C002FFDEC3E0E
|
||||
:081D6800FEAF0580DFE4FEFF81
|
||||
:011D70002250
|
||||
:101EEE007400F58690FDA57C05A3E582458370F907
|
||||
:011EFE0022C1
|
||||
:030000000216B431
|
||||
:0C16B400787FE4F6D8FD75815D0216FB1E
|
||||
:10063B00E709F608DFFA8046E709F208DFFA803EA1
|
||||
:10064B0088828C83E709F0A3DFFA8032E309F6088E
|
||||
:10065B00DFFA8078E309F208DFFA807088828C83F6
|
||||
:10066B00E309F0A3DFFA806489828A83E0A3F608AA
|
||||
:10067B00DFFA805889828A83E0A3F208DFFA804C84
|
||||
:10068B0080D280FA80C680D4806980F2803380105B
|
||||
:10069B0080A680EA809A80A880DA80E280CA8033C4
|
||||
:1006AB0089828A83ECFAE493A3C8C582C8CCC5833C
|
||||
:1006BB00CCF0A3C8C582C8CCC583CCDFE9DEE7800C
|
||||
:1006CB000D89828A83E493A3F608DFF9ECFAA9F08B
|
||||
:1006DB00EDFB2289828A83ECFAE0A3C8C582C8CCE1
|
||||
:1006EB00C583CCF0A3C8C582C8CCC583CCDFEADEFA
|
||||
:1006FB00E880DB89828A83E493A3F208DFF980CC5C
|
||||
:10070B0088F0EF60010E4E60C388F0ED2402B40454
|
||||
:10071B000050B9F582EB2402B4040050AF232345FB
|
||||
:06072B00822390068B738F
|
||||
:10073100BB010689828A83E0225002E722BBFE02C6
|
||||
:09074100E32289828A83E49322F9
|
||||
:10074A00BB010CE58229F582E5833AF583E0225064
|
||||
:10075A0006E92582F8E622BBFE06E92582F8E222AE
|
||||
:0D076A00E58229F582E5833AF583E49322C8
|
||||
:10077700BB010689828A83F0225002F722BBFE0161
|
||||
:02078700F3225B
|
||||
:10078900F8BB010DE58229F582E5833AF583E8F0A6
|
||||
:10079900225006E92582C8F622BBFE05E92582C852
|
||||
:0207A900F2223A
|
||||
:1007AB00EF8DF0A4A8F0CF8CF0A428CE8DF0A42E62
|
||||
:0207BB00FE221C
|
||||
:1007BD00C2D5EC30E709B2D5E4C39DFDE49CFCEE57
|
||||
:1007CD0030E715B2D5E4C39FFFE49EFE120885C342
|
||||
:1007DD00E49DFDE49CFC800312088530D507C3E43D
|
||||
:0607ED009FFFE49EFE22C6
|
||||
:1007F300E8600FECC313FCED13FDEE13FEEF13FFE4
|
||||
:03080300D8F12207
|
||||
:10080600E8600FEFC333FFEE33FEED33FDEC33FC50
|
||||
:03081600D8F122F4
|
||||
:10081900BB010789828A830208E65005E9F80208C4
|
||||
:10082900DABBFE05E9F80208F289828A830208FE2A
|
||||
:10083900BB010789828A830208535005E9F8020936
|
||||
:0A0849000EBBFE05E9F802091A22B1
|
||||
:0C085300ECF0A3EDF0A3EEF0A3EFF02218
|
||||
:10085F00D083D082F8E4937012740193700DA3A328
|
||||
:10086F0093F8740193F5828883E47374029368603C
|
||||
:06087F00EFA3A3A380DF3C
|
||||
:1016C000020CE5E493A3F8E493A34003F68001F24F
|
||||
:1016D00008DFF48029E493A3F85407240CC8C3332B
|
||||
:1016E000C4540F4420C8834004F456800146F6DFFA
|
||||
:1016F000E4800B0102040810204080900F3CE47E3F
|
||||
:10170000019360BCA3FF543F30E509541FFEE493EE
|
||||
:10171000A360010ECF54C025E060A840B8E493A3B5
|
||||
:10172000FAE493A3F8E493A3C8C582C8CAC583CAE0
|
||||
:10173000F0A3C8C582C8CAC583CADFE9DEE780BE98
|
||||
:010FF50000FB
|
||||
:10088500BC000BBE0029EF8DF084FFADF022E4CC57
|
||||
:10089500F875F008EF2FFFEE33FEEC33FCEE9DEC20
|
||||
:1008A500984005FCEE9DFE0FD5F0E9E4CEFD22ED66
|
||||
:1008B500F8F5F0EE8420D21CFEADF075F008EF2FB0
|
||||
:1008C500FFED33FD4007985006D5F0F222C398FDA1
|
||||
:0508D5000FD5F0EA223E
|
||||
:0C08DA00E6FC08E6FD08E6FE08E6FF224A
|
||||
:0C08E600E0FCA3E0FDA3E0FEA3E0FF2285
|
||||
:0C08F200E2FC08E2FD08E2FE08E2FF2242
|
||||
:1008FE00E493FC740193FD740293FE740393FF2240
|
||||
:0C090E00ECF608EDF608EEF608EFF62215
|
||||
:0C091A00ECF208EDF208EEF208EFF22219
|
||||
:00000001FF
|
||||
File diff suppressed because it is too large
Load Diff
421
drivers/dahdi/xpp/firmwares/USB_RECOV.hex
Normal file
421
drivers/dahdi/xpp/firmwares/USB_RECOV.hex
Normal file
@@ -0,0 +1,421 @@
|
||||
#
|
||||
# $Id: USB_RECOV.hex 9760 2011-09-05 12:33:27Z dima $
|
||||
#
|
||||
:03004300021600A2
|
||||
:0300530002160092
|
||||
:10160000021580000215C6000215B00002159800F0
|
||||
:081610000213F20002137B003B
|
||||
:100A00001201000200000040AAAAAAAAAAAA010292
|
||||
:100A100003010A060002000000400100090237003D
|
||||
:100A2000020100C0000904000002FFFFFF040705E7
|
||||
:100A3000020200020007058602000200090401000C
|
||||
:100A400002FFFFFF050705040200020007058802F8
|
||||
:100A5000000200001201000200000040E4E4511115
|
||||
:100A60000000010203010A0600020000004001002C
|
||||
:100A700009023700020100C0320904000002FFFF32
|
||||
:100A8000FF0407050202400000070586024000003F
|
||||
:100A90000904010002FFFFFF0507050402400000F2
|
||||
:100AA000070588024000000604001600140012002A
|
||||
:100AB0000A00260004030904160358006F007200A0
|
||||
:100AC00063006F006D0020004C00540044001403CC
|
||||
:100AD00041007300740072006900620061006E00E2
|
||||
:100AE0006B001203530065007200690061006C0026
|
||||
:100AF0004E006F000A0346005000470041002603E5
|
||||
:100B00004D0061006E00610067006D0065006E00C1
|
||||
:100B10007400500072006F00630065007300730082
|
||||
:060B20006F0072000000EE
|
||||
:08164300584F52434F4D2000A7
|
||||
:100E650041E0B20042E0AD0000021BE0810218E063
|
||||
:100E75007543E0AF0000004CE036393734364D207D
|
||||
:060E8500202020202000C7
|
||||
:101517008B2A8A2B892CE52F152FAE2E7002152EBC
|
||||
:101527004E6014AB2A052CE52CAA2B7002052B1450
|
||||
:08153700F9ED12019280DF22A0
|
||||
:1013B8008B328A338934E5391539AE3870021538DD
|
||||
:1013C8004E6026AB350537E537AA36700205361468
|
||||
:1013D800F912014CFFAB320534E534AA337002052B
|
||||
:0A13E8003314F9EF12019280CD22B8
|
||||
:1011FD008C2A8D2BAA06A9077535018A3689377574
|
||||
:10120D00380075391C7B017AE079481213B890E0EB
|
||||
:10121D0060E0FCA3E0FDA3E0FEA3E064D1FFEE647B
|
||||
:10122D008DFEED644CFDEC6449FC90E06012026EA5
|
||||
:10123D007EE07F487D1C7C00120CFF7EE07F487BAA
|
||||
:10124D001C7A00AD2BAC2A120DB37D1C7C00AF2B8C
|
||||
:10125D00AE2A120C387D1C7C00AF2BAE2A0214284E
|
||||
:08099F008E2A8F2B8C2C8D2D6C
|
||||
:1009A700C204121567BF5004D204803BE4F52EF54C
|
||||
:1009B7002FE52D252FF582E52C352EF583E0FFE574
|
||||
:1009C7002B252FF582E52A352EF583E0B5070E0591
|
||||
:1009D7002FE52F7002052E6410452E70D4E52F6485
|
||||
:0909E70010452E7002D204A20496
|
||||
:0109F00022E4
|
||||
:020875008F32C0
|
||||
:100877001215678F33E4F537F538AD38AC37120FFB
|
||||
:100887001474652538F582E434E0F583E534F00522
|
||||
:1008970038E53870020537C39408E53764809480DB
|
||||
:1008A70040D8E532600490E065F090E065E0B4C0C0
|
||||
:1008B70008753500753608800675351D7536367529
|
||||
:1008C7003700753808C3E5389410E537648094809D
|
||||
:1008D7005023120F1074652538F582E434E0F58350
|
||||
:1008E700E534F00538E538700205370536E536702A
|
||||
:1008F700D4053580D07534FF75351D7536197537B4
|
||||
:1009070000753810C3E538942CE53764809480501F
|
||||
:1009170033E533B4510E7B007A007934AD36AC350C
|
||||
:10092700FF120F1C74652538F582E434E0F583E582
|
||||
:1009370034F00538E538700205370536E53670C4FA
|
||||
:10094700053580C075351D75363EE4F534F537F548
|
||||
:1009570038C3E5389406E53764809480502FE53333
|
||||
:10096700B4510A90E065E0B4C203120F1074422537
|
||||
:1009770038F582E434E0F583E534F00538E538707E
|
||||
:100987000205370536E53670C8053580C490E06541
|
||||
:07099700E0B4C20374C0F0DC
|
||||
:01099E002236
|
||||
:0A12D3008E2A8F2B8B2C8A2D892E7A
|
||||
:1012DD007E00E52B2DF533EE352AF5321215678F8D
|
||||
:1012ED002FE52F6451600BC3E52B9410E52A940074
|
||||
:1012FD005035852A30852B31C3E5319533E5309551
|
||||
:10130D00325024AB2CAA2DA92EAD31AC30AF2F12FB
|
||||
:10131D00117A0531E531700205307401252EF52E57
|
||||
:07132D00E4352DF52D80D100
|
||||
:011334002296
|
||||
:020B26008F320C
|
||||
:100B28007F031214ECEF2402FFE43EA9077533019A
|
||||
:100B3800F534893578367C007D007BFF7A16794359
|
||||
:100B48007E007F08120126E532600464017054E5D6
|
||||
:100B58000C2408F582E4350BF58374B4F0E50C2415
|
||||
:100B680009F582E4350BF5837404F0E50C240AF5E5
|
||||
:100B780082E4350BF5837413F0E50C240BF582E45D
|
||||
:100B8800350BF5837486F0E50C240CF582E4350BFF
|
||||
:100B9800F583E4F0E50C240DF582E4350BF583E4E8
|
||||
:100BA800F0806C90E066E0FFE50C2408F582E435FF
|
||||
:100BB8000BF583EFF090E067E0FFE50C2409F58280
|
||||
:100BC800E4350BF583EFF090E068E0FFE50C240ACC
|
||||
:100BD800F582E4350BF583EFF090E069E0FFE50C72
|
||||
:100BE800240BF582E4350BF583EFF090E06AE0FF23
|
||||
:100BF800E50C240CF582E4350BF583EFF090E06BFF
|
||||
:100C0800E0FFE50C240DF582E4350BF583EFF0E405
|
||||
:100C1800FF74362FF8E6FEAB33AA34A93575F00217
|
||||
:0F0C2800EFA4F58285F083EE1201A40FBF08E25E
|
||||
:010C3700229A
|
||||
:10145E00E4F532E50C240BF582E4350BF583E0FE62
|
||||
:10146E00E50C240AF582E4350BF583E0FDEDFF90E3
|
||||
:10147E00E0ADEEF0A3EFF0D20412000390E680E0B0
|
||||
:03148E0054F7F020
|
||||
:011491002238
|
||||
:10105A0090E600E054E74410F090E60174C0F09086
|
||||
:10106A00E6107420F000000090E611F000000090F5
|
||||
:10107A00E6047480F0000000740FF0000000E4F051
|
||||
:10108A0000000090E6187410F0000000E490E619E1
|
||||
:10109A00F000000090E61A7408F0000000E490E600
|
||||
:1010AA001BF000000090E6497482F0000000F00096
|
||||
:1010BA00000090E6247402F0000000E490E625F0B7
|
||||
:1010CA0000000090E6957480F0000000F000000037
|
||||
:1010DA0043AF017B017AE07914752E00752F06E47F
|
||||
:0410EA00FD021517D7
|
||||
:1015DC007C007D181201C6EF1FAC0670011E4C700A
|
||||
:0215EC00F622E5
|
||||
:1015670090E678E0541824F06008240870087F504B
|
||||
:0815770080067F518002E4FFB1
|
||||
:01157F002249
|
||||
:0C0F1000AD36AC357B007A007934AF338D
|
||||
:0C0F1C008F398C3A8D3B8B3C8A3D893E1E
|
||||
:100F2800E4F53FF540754103FDF542F543A2AF33C3
|
||||
:100F3800F544E53924AF600D047012753F00754023
|
||||
:100F4800017D018008753F00754002E4FDE53960C8
|
||||
:100F580051E540453F604BE53A90E0AFF0E53BA3F3
|
||||
:100F6800F074AF2DF582E434E0AD82FCAB40AF39CC
|
||||
:100F780012126D7542008F437F0A7E00121335E509
|
||||
:100F880043454260107CE07D647B01AF39120FB5A8
|
||||
:100F98007542008F4390E064E0AB3CAA3DA93E1245
|
||||
:0C0FA8000192E54424FF92AFAE42AF433B
|
||||
:010FB400221A
|
||||
:0C117A008F348C358D368B378A388939DC
|
||||
:10118600E4F53AF53B753C03FDF53DF53EA2AF337C
|
||||
:10119600F53FE53424AF600D047012753A00753BD7
|
||||
:1011A600027D018008753A00753B03E4FDE5346075
|
||||
:1011B6003BE53B453A6035E53590E0AFF0E536A3D3
|
||||
:1011C600F0AB37AA38A93912014C90E0B1F074AFF0
|
||||
:1011D6002DF582E434E0AD82FCAB3BAF3412126DE8
|
||||
:1011E600753D008F3E7F0A7E00121335E53F24FFD2
|
||||
:0611F60092AFAE3DAF3EDA
|
||||
:0111FC0022D0
|
||||
:10054300E4F52AF52BF52CF52DF52EF52FF530E5F1
|
||||
:10055300AA5484600302071190E694E0FE90E695A6
|
||||
:10056300E0FBEEF52DEBF52EC39405E52D9400404D
|
||||
:100573000790F404E0FD80027DFFED24F570030293
|
||||
:10058300062524E6700302064F24E0700302062CBE
|
||||
:1005930024FE7003020649243960030206B3752A58
|
||||
:1005A30000752B0590FC04748EF01215678F30E5EF
|
||||
:1005B3003064516019E53064506013752A00752B5F
|
||||
:1005C3000690FC047480F0A3740BF00206D6121597
|
||||
:1005D300678F307B007A007931E4FDFC120F1CAF8A
|
||||
:1005E300311208757400252BF974FC352AFA7B0146
|
||||
:1005F300C0038B357536E075376575380075392C52
|
||||
:10060300D0031213B87400252BF58274FC352AF538
|
||||
:1006130083E531F0742C252BF52BE4352AF52A02DA
|
||||
:1006230006D6E4F52AF52B801D1215678F307B0063
|
||||
:100633007A007931E4FDFC120F1CAF311208757F8B
|
||||
:10064300C0120B26800012145E0206D6752A0075AE
|
||||
:100653002B0590FC0474A5F01215678F307B007A8C
|
||||
:10066300007931E4FDFC120F1C052BE52BAE2A703B
|
||||
:1006730002052A142400F58274FC3EF583E508F094
|
||||
:10068300052BE52BAE2A7002052A142400F582748B
|
||||
:10069300FC3EF583E515F0052BE52BAE2A7002052C
|
||||
:1006A3002A142400F58274FC3EF583E531F080239F
|
||||
:1006B300752A00752B0690FC047480F0C3E52E9414
|
||||
:1006C30005E52D94005006A37407F0800690FC0501
|
||||
:1006D3007406F0E52B452A602CE52BFD90FC00F019
|
||||
:1006E300E52AFFA3F090F402E090FC02F090F403FB
|
||||
:1006F300E090FC03F090E69CEFF000000090E69D94
|
||||
:0E070300EDF000000090E6957480F00000001C
|
||||
:0107110022C5
|
||||
:02004100D322C8
|
||||
:0800460090E6BAE0F51DD3229B
|
||||
:1015EE0090E740E51DF0E490E68AF090E68B04F07B
|
||||
:0215FE00D322F6
|
||||
:08163B0090E6BAE0F51AD32293
|
||||
:1016180090E740E51AF0E490E68AF090E68B04F053
|
||||
:02162800D322CB
|
||||
:10153F0090E6B9E0242F600D04701990E604E0FFE7
|
||||
:10154F00430780800890E604E0FF53077F00000008
|
||||
:07155F00EFF08002D322C36C
|
||||
:011566002262
|
||||
:10158000C0E0C083C082D2015391EF90E65D740148
|
||||
:08159000F0D082D083D0E032DC
|
||||
:1015B000C0E0C083C0825391EF90E65D7404F0D028
|
||||
:0615C00082D083D0E0326E
|
||||
:1015C600C0E0C083C0825391EF90E65D7402F0D014
|
||||
:0615D60082D083D0E03258
|
||||
:1013F200C0E0C083C08285110D85120E850E8285E4
|
||||
:101402000D83A37402F085090F850A108510828569
|
||||
:101412000F83A37407F05391EF90E65D7410F0D040
|
||||
:0614220082D083D0E0320D
|
||||
:10159800C0E0C083C082D2035391EF90E65D740827
|
||||
:0815A800F0D082D083D0E032C4
|
||||
:10137B00C0E0C083C08290E680E030E72085090D95
|
||||
:10138B00850A0E850E82850D83A37402F085110FDD
|
||||
:10139B00851210851082850F83A37407F05391EF8C
|
||||
:0D13AB0090E65D7420F0D082D083D0E03257
|
||||
:0E09F10000010202030304040505C0C2000059
|
||||
:1007120078237C007D007BFF7A0979FB7E007F04D1
|
||||
:10072200120126C203C200D202C20112105A750B74
|
||||
:100732000A750C0075130A75141275090A750A1CDC
|
||||
:1007420075110A75127085110F85121075160A75CA
|
||||
:1007520017B41215678F217B007A007922E4FDFC21
|
||||
:10076200120F1C852208E4F515F52774232527F8B6
|
||||
:10077200E6FF605C1208757EE07F657CE07DB31267
|
||||
:1007820011FD7EE07FB3AD1CAC1B12099F50387483
|
||||
:10079200232527F8E6F515652260277B007A007984
|
||||
:1007A200157D01E4FFFE1212D37B007A007922E468
|
||||
:1007B200FDFCAF21120F1CE52265156013751501B2
|
||||
:1007C200800E7515FF80090527E527C39404409B19
|
||||
:1007D200E5157059FB7A0079227D01FCAF21120FD9
|
||||
:1007E2001CE522752900F5287B007A0079227D021A
|
||||
:1007F2007C00AF21120F1CE5224229E52964E47036
|
||||
:1008020004E52864E470267515C0FB7A0079157D2D
|
||||
:1008120001FFFE1212D37B007A007922E4FDFCAFC5
|
||||
:1008220021120F1CE52265156003751501AF151223
|
||||
:100832000B26D2E843D82090E668E04409F090E61F
|
||||
:100842005CE0443DF0E51564C06005E515B4C20303
|
||||
:1008520012145ED2AF538EF8C203C2AF120543D256
|
||||
:10086200AF30010512031BC2013003EEC2031214A2
|
||||
:03087200C080E75C
|
||||
:0B00360090E50DE030E402C322D3226D
|
||||
:10031B0090E6B9E070030203E01470030204552465
|
||||
:10032B00FE70030204D024FB70030203DA14700383
|
||||
:10033B000203D41470030203C81470030203CE2407
|
||||
:10034B0005600302052F120041400302053B90E6B6
|
||||
:10035B00BBE024FE602714603E24FD60111460276F
|
||||
:10036B0024067056E50B90E6B3F0E50C80421200C4
|
||||
:10037B00365044E51390E6B3F0E5148033E50D9069
|
||||
:10038B00E6B3F0E50E802985110F851210E50F906D
|
||||
:10039B00E6B3F0E510801990E6BAE0FF1214ECAA70
|
||||
:1003AB0006A9077B01EA494B600DEE90E6B3F0EF2F
|
||||
:1003BB0090E6B4F002053B02052A02052A12161834
|
||||
:1003CB0002053B12163B02053B12004602053B128F
|
||||
:1003DB0015EE02053B90E6B8E0247F60151460191A
|
||||
:1003EB0024027063A200E43325E0FFA202E4334F42
|
||||
:1003FB008041E490E740F0803F90E6BCE0547EFF04
|
||||
:10040B007E00E0D394807C0040047D0180027D005F
|
||||
:10041B00EC4EFEED4F24F1F58274093EF583E49327
|
||||
:10042B00FF3395E0FEEF24A1FFEE34E68F82F583D8
|
||||
:10043B00E0540190E740F0E4A3F090E68AF090E6F8
|
||||
:10044B008B7402F002053B02052A90E6B8E024FE0D
|
||||
:10045B0060162402600302053B90E6BAE0B4010586
|
||||
:10046B00C20002053B02052A90E6BAE0705590E601
|
||||
:10047B00BCE0547EFF7E00E0D394807C0040047D82
|
||||
:10048B000180027D00EC4EFEED4F24F1F5827409E4
|
||||
:10049B003EF583E493FF3395E0FEEF24A1FFEE34AA
|
||||
:1004AB00E68F82F583E054FEF090E6BCE0548013B7
|
||||
:1004BB001313541FFFE0540F2F90E683F0E04420FA
|
||||
:1004CB00F0806D805A90E6B8E024FE60192402702B
|
||||
:1004DB004E90E6BAE0B40104D200805490E6BAE044
|
||||
:1004EB006402604C803990E6BCE0547EFF7E00E0F5
|
||||
:1004FB00D394807C0040047D0180027D00EC4EFE95
|
||||
:10050B00ED4F24F1F58274093EF583E493FF3395A7
|
||||
:10051B00E0FEEF24A1FFEE34E68F82F583800D9091
|
||||
:10052B00E6A0800812153F500790E6A0E04401F0CA
|
||||
:07053B0090E6A0E04480F00F
|
||||
:010542002296
|
||||
:0300330002004E7A
|
||||
:04004E0053D8EF3262
|
||||
:100E8B006080E0CF292E43C9A2D87C013D3654A106
|
||||
:100E9B00ECF0061362A705F3C0C7738C98932BD99C
|
||||
:100EAB00BC4C82CA1E9B573CFDD4E01667426F18A0
|
||||
:100EBB008A17E512BE4EC4D6DA9EDE49A0FBF58E2C
|
||||
:100ECB00BB2FEE7AA968799115B2073F94C21089AE
|
||||
:100EDB000B225F21807F5D9A5A903227353ECCE7FB
|
||||
:100EEB00BFF79703FF1930B348A5B5D1D75E922A48
|
||||
:100EFB00AC56AAC64FB838D296A47DB676FC6BE238
|
||||
:040F0B009C7404F1DD
|
||||
:080CFF008C2C8D2DAB07AA0619
|
||||
:100D0700E4F52EF52FC3E52F952DE52C6480F8E546
|
||||
:100D17002E6480984003020DAEE52F25E0FFE52EF7
|
||||
:100D270033FE74CF2FF58274E03EF583E0FF7E003B
|
||||
:100D3700AC2CAD2D1201D88C308D31E52F25E0FF7D
|
||||
:100D4700E52E33FE74D02FF58274E03EF583E0FF85
|
||||
:100D57007E00AC2CAD2D1201D88C328D33E5316578
|
||||
:100D6700337004E53065326030EB2531F582EA35C2
|
||||
:100D770030F583E0F9EB2533F582EA3532F583E088
|
||||
:100D8700FFEB2531F582EA3530F583EFF0EB2533BC
|
||||
:100D9700F582EA3532F583E9F0052FE52F60030286
|
||||
:0B0DA7000D0C052E020D0C7E007F01DC
|
||||
:010DB200221E
|
||||
:0C0DB3008E2C8F2D8C2E8D2F8A308B31D2
|
||||
:100DBF00E52D452C6006E52F452E7004E4FEFF223D
|
||||
:100DCF00E4F532F533C3E5339531E5306480F8E56A
|
||||
:100DDF0032648098507BE4F534F535E52F2533F5F3
|
||||
:100DEF0082E52E3532F583E4F0C3E5359531E530F4
|
||||
:100DFF006480F8E5346480985049E535253324CF75
|
||||
:100E0F00F582E434E0F583E0FFE52D2535F582E545
|
||||
:100E1F002C3534F583E0FEEF8EF0A4FFE52F25335C
|
||||
:100E2F00F582E52E3532F583E02FFFE52F2533F5DB
|
||||
:100E3F0082E52E3532F583EFF00535E53570AA05DD
|
||||
:100E4F003480A60533E5336003020DD40532020D5D
|
||||
:050E5F00D47E007F01BC
|
||||
:010E6400226B
|
||||
:1014920012014CFF900003120165120192900003A9
|
||||
:1014A200EF1201A4900002120165FF9000011201E7
|
||||
:0E14B200659000021201A4900001EF0201A457
|
||||
:080C38008E2C8F2D8C2E8D2FC8
|
||||
:100C4000E4F530F531E52FAE2E7802CEA2E713CED3
|
||||
:100C500013D8F8FFC3E5319FEE6480F8E530648077
|
||||
:100C6000984003020CFAE531AE307802C333CE333C
|
||||
:100C7000CED8F9252DFFEE352CFAA9077B018B3252
|
||||
:100C8000F533893474D02531F582E434E0F583E01E
|
||||
:100C9000541FFFE48F38F537F536F535121492AB53
|
||||
:100CA00032AA33A934120234C374209538F9F812E9
|
||||
:100CB0000221C004C005C006C007A934120234A92D
|
||||
:100CC00038A80112020ED003D002D001D000EF4BA1
|
||||
:100CD000FFEE4AFEED49FDEC48FCAB32AA33A934E5
|
||||
:100CE000120254AB32AA33A9341214920531E53101
|
||||
:0E0CF0006003020C450530020C457E007F01BA
|
||||
:010CFE0022D3
|
||||
:10142800D3ED9410EC64809480402AED1D70011C6B
|
||||
:10143800142FF582EE3CF583E0FB547F24CFF58230
|
||||
:10144800E434E0F583E0F9540F2FF582E43EF583A8
|
||||
:05145800E06BF080CB09
|
||||
:01145D00226C
|
||||
:1014C00090E682E030E004E020E60B90E682E03037
|
||||
:1014D000E119E030E71590E680E04401F07F147EEA
|
||||
:0C14E0000012133590E680E054FEF0226C
|
||||
:1000030030040990E680E0440AF0800790E680E03F
|
||||
:100013004408F07FDC7E0512133590E65D74FFF033
|
||||
:0F00230090E65FF05391EF90E680E054F7F02203
|
||||
:101335008E458F4690E600E054187012E54624016C
|
||||
:10134500FFE43545C313F545EF13F546801590E6E3
|
||||
:1013550000E05418FFBF100BE54625E0F546E545CE
|
||||
:1013650033F545E5461546AE45700215454E600513
|
||||
:0613750012162A80EE2290
|
||||
:060FB5008C458D46AE07DD
|
||||
:100FBB00EB70037F012290E678E020E6F990E6786B
|
||||
:100FCB007480F0EE25E0440190E679F090E678E04D
|
||||
:100FDB0030E0F990E678E020E26BE030E167BB01AE
|
||||
:100FEB000790E678E04420F090E679E0F5471BEBBC
|
||||
:100FFB00603090E678E030E0F990E678E020E2456A
|
||||
:10100B00BB010790E678E04420F090E679E0FF051D
|
||||
:10101B0046E546AC457002054514F5828C83EFF02E
|
||||
:10102B0080CC90E678E030E0F990E678E020E215AD
|
||||
:10103B0090E678E04440F090E679E085468285457D
|
||||
:0E104B0083F07F012290E678E04440F07F00C1
|
||||
:011059002274
|
||||
:10126D0090E678E020E6F990E6787480F0EF25E0DE
|
||||
:10127D0090E679F090E678E030E0F990E678E020BD
|
||||
:10128D00E23AE030E136EBD3940040260DEDAE04AA
|
||||
:10129D0070010C14F5828E83E090E679F01B90E6D8
|
||||
:1012AD0078E030E0F990E678E020E210E020E1D639
|
||||
:1012BD00800A90E678E04440F07F012290E678E0E5
|
||||
:0512CD004440F07F0029
|
||||
:0112D20022F9
|
||||
:0214EC00A9074E
|
||||
:1014EE00AE16AF178F828E83A3E064037017AD0123
|
||||
:1014FE0019ED7001228F828E83E07C002FFDEC3E71
|
||||
:08150E00FEAF0580DFE4FEFFE3
|
||||
:0115160022B2
|
||||
:10162A007400F58690FDA57C05A3E582458370F9D3
|
||||
:01163A00228D
|
||||
:030000000210EEFD
|
||||
:0C10EE00787FE4F6D8FD758147021135CB
|
||||
:10005600E709F608DFFA8046E709F208DFFA803E8C
|
||||
:1000660088828C83E709F0A3DFFA8032E309F60879
|
||||
:10007600DFFA8078E309F208DFFA807088828C83E1
|
||||
:10008600E309F0A3DFFA806489828A83E0A3F60895
|
||||
:10009600DFFA805889828A83E0A3F208DFFA804C6F
|
||||
:1000A60080D280FA80C680D4806980F28033801046
|
||||
:1000B60080A680EA809A80A880DA80E280CA8033AF
|
||||
:1000C60089828A83ECFAE493A3C8C582C8CCC58327
|
||||
:1000D600CCF0A3C8C582C8CCC583CCDFE9DEE780F7
|
||||
:1000E6000D89828A83E493A3F608DFF9ECFAA9F076
|
||||
:1000F600EDFB2289828A83ECFAE0A3C8C582C8CCCC
|
||||
:10010600C583CCF0A3C8C582C8CCC583CCDFEADEE4
|
||||
:10011600E880DB89828A83E493A3F208DFF980CC46
|
||||
:1001260088F0EF60010E4E60C388F0ED2402B4043F
|
||||
:100136000050B9F582EB2402B4040050AF232345E6
|
||||
:0601460082239000A67365
|
||||
:10014C00BB010689828A83E0225002E722BBFE02B1
|
||||
:09015C00E32289828A83E49322E4
|
||||
:10016500BB010CE58229F582E5833AF583E022504F
|
||||
:1001750006E92582F8E622BBFE06E92582F8E22299
|
||||
:0D018500E58229F582E5833AF583E49322B3
|
||||
:10019200BB010689828A83F0225002F722BBFE014C
|
||||
:0201A200F32246
|
||||
:1001A400F8BB010DE58229F582E5833AF583E8F091
|
||||
:1001B400225006E92582C8F622BBFE05E92582C83D
|
||||
:0201C400F22225
|
||||
:1001C600EF8DF0A4A8F0CF8CF0A428CE8DF0A42E4D
|
||||
:0201D600FE2207
|
||||
:1001D800C2D5EC30E709B2D5E4C39DFDE49CFCEE42
|
||||
:1001E80030E715B2D5E4C39FFFE49EFE12027AC33E
|
||||
:1001F800E49DFDE49CFC800312027A30D507C3E439
|
||||
:060208009FFFE49EFE22B0
|
||||
:10020E00E8600FECC313FCED13FDEE13FEEF13FFCE
|
||||
:03021E00D8F122F2
|
||||
:10022100E8600FEFC333FFEE33FEED33FDEC33FC3B
|
||||
:03023100D8F122DF
|
||||
:10023400BB010789828A830202DB5005E9F80202C6
|
||||
:10024400CFBBFE05E9F80202E789828A830202F342
|
||||
:10025400BB010789828A8302026E5005E9F8020312
|
||||
:0A02640003BBFE05E9F802030F22B8
|
||||
:0C026E00ECF0A3EDF0A3EEF0A3EFF02203
|
||||
:1010FA00020712E493A3F8E493A34003F68001F2F3
|
||||
:10110A0008DFF48029E493A3F85407240CC8C333F6
|
||||
:10111A00C4540F4420C8834004F456800146F6DFC5
|
||||
:10112A00E4800B0102040810204080900E65E47EE2
|
||||
:10113A00019360BCA3FF543F30E509541FFEE493BA
|
||||
:10114A00A360010ECF54C025E060A840B8E493A381
|
||||
:10115A00FAE493A3F8E493A3C8C582C8CAC583CAAC
|
||||
:10116A00F0A3C8C582C8CAC583CADFE9DEE780BE64
|
||||
:010F0F0000E1
|
||||
:10027A00BC000BBE0029EF8DF084FFADF022E4CC68
|
||||
:10028A00F875F008EF2FFFEE33FEEC33FCEE9DEC31
|
||||
:10029A00984005FCEE9DFE0FD5F0E9E4CEFD22ED77
|
||||
:1002AA00F8F5F0EE8420D21CFEADF075F008EF2FC1
|
||||
:1002BA00FFED33FD4007985006D5F0F222C398FDB2
|
||||
:0502CA000FD5F0EA224F
|
||||
:0C02CF00E6FC08E6FD08E6FE08E6FF225B
|
||||
:0C02DB00E0FCA3E0FDA3E0FEA3E0FF2296
|
||||
:0C02E700E2FC08E2FD08E2FE08E2FF2253
|
||||
:1002F300E493FC740193FD740293FE740393FF2251
|
||||
:0C030300ECF608EDF608EEF608EFF62226
|
||||
:0C030F00ECF208EDF208EEF208EFF2222A
|
||||
:00000001FF
|
||||
@@ -51,6 +51,7 @@ BEGIN { $init_dir = dirname($0); unshift(@INC, "$init_dir"); }
|
||||
use XppConfig $init_dir;
|
||||
my $unit_id;
|
||||
my %opts;
|
||||
my $vbat_48 = 0;
|
||||
|
||||
getopts('o:', \%opts);
|
||||
|
||||
@@ -78,6 +79,7 @@ if (-t STDERR) {
|
||||
foreach my $k (qw(
|
||||
XBUS_NAME
|
||||
XBUS_NUMBER
|
||||
XBUS_MODEL_STRING
|
||||
UNIT_NUMBER
|
||||
UNIT_TYPE
|
||||
UNIT_SUBUNITS
|
||||
@@ -90,6 +92,10 @@ if (-t STDERR) {
|
||||
die;
|
||||
}
|
||||
}
|
||||
logit "XBUS_MODEL_STRING='$ENV{XBUS_MODEL_STRING}'";
|
||||
if ($ENV{XBUS_MODEL_STRING} =~ m{.*/.*/201}) {
|
||||
$vbat_48 = 1;
|
||||
}
|
||||
$chipregs = sprintf "/sys/bus/xpds/devices/%02d:%1d:0/chipregs",
|
||||
$ENV{XBUS_NUMBER}, $ENV{UNIT_NUMBER};
|
||||
if(! -f $chipregs) {
|
||||
@@ -286,11 +292,15 @@ sub init_indirect_registers() {
|
||||
}
|
||||
|
||||
sub init_early_direct_regs() {
|
||||
my $lbv = ($vbat_48) ? "20" : "10";
|
||||
my $vcm = ($vbat_48) ? "02" : "03";
|
||||
|
||||
return write_to_slic_file("#
|
||||
* WD 08 00 # Audio Path Loopback Control
|
||||
* WD 6C 01
|
||||
* WD 4A 3F # High Battery Voltage
|
||||
* WD 4B 10 # Low Battery Voltage
|
||||
* WD 4B $lbv # Low Battery Voltage
|
||||
* WD 49 $vcm # Common Mode Voltage (VCM)
|
||||
* WD 40 00 # Line Feed Control
|
||||
#")
|
||||
}
|
||||
@@ -578,9 +588,6 @@ __DATA__
|
||||
# On-Hook Line Voltage (VOC)
|
||||
* WD 48 20
|
||||
|
||||
# Common Mode Voltage (VCM)
|
||||
* WD 49 03
|
||||
|
||||
* WS 1E 23 00 80
|
||||
* WS 1E 24 20 03
|
||||
* WS 1E 25 8C 00
|
||||
|
||||
@@ -58,9 +58,11 @@ static int proc_xbus_command_write(struct file *file, const char __user *buffer,
|
||||
|
||||
/* Command line parameters */
|
||||
extern int debug;
|
||||
static DEF_PARM(uint, command_queue_length, 1000, 0444, "Maximal command queue length");
|
||||
static DEF_PARM(uint, command_queue_length, 1500, 0444, "Maximal command queue length");
|
||||
static DEF_PARM(uint, poll_timeout, 1000, 0644, "Timeout (in jiffies) waiting for units to reply");
|
||||
static DEF_PARM_BOOL(rx_tasklet, 0, 0644, "Use receive tasklets");
|
||||
static DEF_PARM_BOOL(dahdi_autoreg, 0, 0644,
|
||||
"Register devices automatically (1) or not (0)");
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
static int xbus_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
|
||||
@@ -776,7 +778,6 @@ static int xpd_initialize(xpd_t *xpd)
|
||||
goto out;
|
||||
}
|
||||
XPD_INFO(xpd, "Initialized: %s\n", xpd->type_name);
|
||||
xpd_post_init(xpd);
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
@@ -810,6 +811,29 @@ static int xbus_echocancel(xbus_t *xbus, int on)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xbus_deactivate_xpds(xbus_t *xbus)
|
||||
{
|
||||
unsigned long flags;
|
||||
int unit;
|
||||
int subunit;
|
||||
xpd_t *xpd;
|
||||
|
||||
for (unit = 0; unit < MAX_UNIT; unit++) {
|
||||
xpd = xpd_byaddr(xbus, unit, 0);
|
||||
if (!xpd)
|
||||
continue;
|
||||
for (subunit = 0; subunit < MAX_SUBUNIT; subunit++) {
|
||||
xpd = xpd_byaddr(xbus, unit, subunit);
|
||||
if (!xpd)
|
||||
continue;
|
||||
spin_lock_irqsave(&xpd->lock, flags);
|
||||
xpd->card_present = 0;
|
||||
xpd_setstate(xpd, XPD_STATE_NOHW);
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int xbus_initialize(xbus_t *xbus)
|
||||
{
|
||||
int unit;
|
||||
@@ -871,6 +895,120 @@ err:
|
||||
goto out;
|
||||
}
|
||||
|
||||
int xbus_is_registered(xbus_t *xbus)
|
||||
{
|
||||
return xbus->ddev && xbus->ddev->dev.parent;
|
||||
}
|
||||
|
||||
static void xbus_free_ddev(xbus_t *xbus)
|
||||
{
|
||||
if (!xbus->ddev)
|
||||
return;
|
||||
if (xbus->ddev->devicetype)
|
||||
kfree(xbus->ddev->devicetype);
|
||||
xbus->ddev->devicetype = NULL;
|
||||
xbus->ddev->location = NULL;
|
||||
xbus->ddev->hardware_id = NULL;
|
||||
dahdi_free_device(xbus->ddev);
|
||||
xbus->ddev = NULL;
|
||||
}
|
||||
|
||||
int xbus_register_dahdi_device(xbus_t *xbus)
|
||||
{
|
||||
int i;
|
||||
int offset = 0;
|
||||
int ret;
|
||||
|
||||
XBUS_DBG(DEVICES, xbus, "Entering %s\n", __func__);
|
||||
if (xbus_is_registered(xbus)) {
|
||||
XBUS_ERR(xbus, "Already registered to DAHDI\n");
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
xbus->ddev = dahdi_create_device();
|
||||
if (!xbus->ddev) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* This actually describe the dahdi_spaninfo version 3
|
||||
* A bunch of unrelated data exported via a modified ioctl()
|
||||
* What a bummer...
|
||||
*/
|
||||
xbus->ddev->manufacturer = "Xorcom Inc."; /* OK, that's obvious */
|
||||
/* span->spantype = "...."; set in card_dahdi_preregistration() */
|
||||
/*
|
||||
* Yes, this basically duplicates information available
|
||||
* from the description field. If some more is needed
|
||||
* why not add it there?
|
||||
* OK, let's add to the kernel more useless info.
|
||||
*/
|
||||
xbus->ddev->devicetype = kasprintf(GFP_KERNEL, "Astribank2");
|
||||
if (!xbus->ddev->devicetype) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* location is the only usefull new data item.
|
||||
* For our devices it was available for ages via:
|
||||
* - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...)
|
||||
* - The same info in "/proc/xpp/xbuses"
|
||||
* - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute
|
||||
* So let's also export it via the newfangled "location" field.
|
||||
*/
|
||||
xbus->ddev->location = xbus->connector;
|
||||
xbus->ddev->hardware_id = xbus->label;
|
||||
|
||||
/*
|
||||
* Prepare the span list
|
||||
*/
|
||||
for (i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
if (xpd && IS_PHONEDEV(xpd)) {
|
||||
XPD_DBG(DEVICES, xpd, "offset=%d\n", offset);
|
||||
xpd_dahdi_preregister(xpd, offset++);
|
||||
}
|
||||
}
|
||||
if (dahdi_register_device(xbus->ddev, &xbus->astribank)) {
|
||||
XBUS_ERR(xbus, "Failed to dahdi_register_device()\n");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
if (xpd && IS_PHONEDEV(xpd)) {
|
||||
XPD_DBG(DEVICES, xpd, "\n");
|
||||
xpd_dahdi_postregister(xpd);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
xbus_free_ddev(xbus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void xbus_unregister_dahdi_device(xbus_t *xbus)
|
||||
{
|
||||
int i;
|
||||
|
||||
XBUS_NOTICE(xbus, "%s\n", __func__);
|
||||
for(i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
xpd_dahdi_preunregister(xpd);
|
||||
}
|
||||
if (xbus->ddev) {
|
||||
dahdi_unregister_device(xbus->ddev);
|
||||
XBUS_NOTICE(xbus, "%s: finished dahdi_unregister_device()\n", __func__);
|
||||
xbus_free_ddev(xbus);
|
||||
}
|
||||
for(i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
xpd_dahdi_postunregister(xpd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This must be called from synchronous (non-interrupt) context
|
||||
* it returns only when all XPD's on the bus are detected and
|
||||
@@ -934,6 +1072,8 @@ void xbus_populate(void *data)
|
||||
*/
|
||||
xbus_request_sync(xbus, SYNC_MODE_PLL);
|
||||
elect_syncer("xbus_populate(end)"); /* FIXME: try to do it later */
|
||||
if (dahdi_autoreg)
|
||||
xbus_register_dahdi_device(xbus);
|
||||
out:
|
||||
XBUS_DBG(DEVICES, xbus, "Leaving\n");
|
||||
wake_up_interruptible_all(&worker->wait_for_xpd_initialization);
|
||||
@@ -1206,12 +1346,13 @@ void xbus_deactivate(xbus_t *xbus)
|
||||
xbus_request_sync(xbus, SYNC_MODE_NONE); /* no more ticks */
|
||||
elect_syncer("deactivate");
|
||||
xbus_echocancel(xbus, 0);
|
||||
xbus_request_removal(xbus);
|
||||
xbus_deactivate_xpds(xbus);
|
||||
XBUS_DBG(DEVICES, xbus, "[%s] Waiting for queues\n", xbus->label);
|
||||
xbus_command_queue_clean(xbus);
|
||||
xbus_command_queue_waitempty(xbus);
|
||||
xbus_setstate(xbus, XBUS_STATE_DEACTIVATED);
|
||||
worker_reset(xbus);
|
||||
xbus_unregister_dahdi_device(xbus);
|
||||
xbus_release_xpds(xbus); /* taken in xpd_alloc() [kref_init] */
|
||||
}
|
||||
|
||||
@@ -1316,7 +1457,6 @@ xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *tran
|
||||
xbus = xbus_alloc();
|
||||
if(!xbus) {
|
||||
ERR("%s: Failed allocating new xbus\n", __FUNCTION__);
|
||||
module_put(THIS_MODULE);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(xbus->busname, XBUS_NAMELEN, "XBUS-%02d", xbus->num);
|
||||
@@ -1788,10 +1928,6 @@ err:
|
||||
|
||||
void xbus_core_shutdown(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAX_BUSES; i++)
|
||||
BUG_ON(xbus_num(i));
|
||||
xbus_core_cleanup();
|
||||
xpp_driver_exit();
|
||||
}
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
#include "xframe_queue.h"
|
||||
#include "xbus-pcm.h"
|
||||
|
||||
#define MAX_BUSES 32
|
||||
#define XFRAME_DATASIZE 512
|
||||
#define MAX_BUSES 128
|
||||
#define XFRAME_DATASIZE 512
|
||||
#define MAX_ENV_STR 40
|
||||
|
||||
/* forward declarations */
|
||||
struct xbus_workqueue;
|
||||
@@ -108,6 +109,7 @@ struct xbus_transport {
|
||||
atomic_t transport_refcount;
|
||||
wait_queue_head_t transport_unused;
|
||||
spinlock_t lock;
|
||||
char model_string[MAX_ENV_STR];
|
||||
};
|
||||
|
||||
#define MAX_SEND_SIZE(xbus) ((xbus)->transport.max_send_size)
|
||||
@@ -188,6 +190,7 @@ struct xbus {
|
||||
char label[LABEL_SIZE];
|
||||
byte revision; /* Protocol revision */
|
||||
struct xbus_transport transport;
|
||||
struct dahdi_device *ddev;
|
||||
|
||||
int num;
|
||||
struct xpd *xpds[MAX_XPDS];
|
||||
@@ -340,6 +343,10 @@ int xpd_device_register(xbus_t *xbus, xpd_t *xpd);
|
||||
void xpd_device_unregister(xpd_t *xpd);
|
||||
int echocancel_xpd(xpd_t *xpd, int on);
|
||||
|
||||
int xbus_is_registered(xbus_t *xbus);
|
||||
int xbus_register_dahdi_device(xbus_t *xbus);
|
||||
void xbus_unregister_dahdi_device(xbus_t *xbus);
|
||||
|
||||
int xpp_driver_init(void);
|
||||
void xpp_driver_exit(void);
|
||||
int xbus_sysfs_transport_create(xbus_t *xbus);
|
||||
|
||||
@@ -438,16 +438,6 @@ static void astribank_release(struct device *dev)
|
||||
xbus_free(xbus);
|
||||
}
|
||||
|
||||
static void toplevel_release(struct device *dev)
|
||||
{
|
||||
NOTICE("%s\n", __func__);
|
||||
}
|
||||
|
||||
static struct device toplevel_device = {
|
||||
.release = toplevel_release,
|
||||
/* No Parent */
|
||||
};
|
||||
|
||||
static struct bus_type toplevel_bus_type = {
|
||||
.name = "astribanks",
|
||||
.match = astribank_match,
|
||||
@@ -623,6 +613,10 @@ static DEVICE_ATTR_READER(span_show, dev, buf)
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* For backward compatibility with old dahdi-tools
|
||||
* Remove after dahdi_registration is upgraded
|
||||
*/
|
||||
static DEVICE_ATTR_WRITER(span_store, dev, buf, count)
|
||||
{
|
||||
xpd_t *xpd;
|
||||
@@ -631,19 +625,34 @@ static DEVICE_ATTR_WRITER(span_store, dev, buf, count)
|
||||
|
||||
BUG_ON(!dev);
|
||||
xpd = dev_to_xpd(dev);
|
||||
if(!xpd)
|
||||
if (!xpd)
|
||||
return -ENODEV;
|
||||
ret = sscanf(buf, "%d", &dahdi_reg);
|
||||
if(ret != 1)
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
if(!XBUS_IS(xpd->xbus, READY))
|
||||
if (!XBUS_IS(xpd->xbus, READY))
|
||||
return -ENODEV;
|
||||
XPD_DBG(GENERAL, xpd, "%s\n", (dahdi_reg) ? "register" : "unregister");
|
||||
if(dahdi_reg)
|
||||
ret = dahdi_register_xpd(xpd);
|
||||
else
|
||||
ret = dahdi_unregister_xpd(xpd);
|
||||
return (ret < 0) ? ret : count;
|
||||
XPD_DBG(DEVICES, xpd,
|
||||
"%s -- deprecated (should use pinned-spans)\n",
|
||||
(dahdi_reg) ? "register" : "unregister");
|
||||
if (xbus_is_registered(xpd->xbus)) {
|
||||
if (dahdi_reg) {
|
||||
XPD_DBG(DEVICES, xpd,
|
||||
"already registered %s. Ignored.\n",
|
||||
xpd->xbus->busname);
|
||||
} else {
|
||||
xbus_unregister_dahdi_device(xpd->xbus);
|
||||
}
|
||||
} else {
|
||||
if (!dahdi_reg) {
|
||||
XPD_DBG(DEVICES, xpd,
|
||||
"already unregistered %s. Ignored.\n",
|
||||
xpd->xbus->busname);
|
||||
} else {
|
||||
xbus_register_dahdi_device(xpd->xbus);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_READER(type_show, dev, buf)
|
||||
@@ -964,7 +973,7 @@ int xbus_sysfs_create(xbus_t *xbus)
|
||||
astribank = &xbus->astribank;
|
||||
XBUS_DBG(DEVICES, xbus, "\n");
|
||||
astribank->bus = &toplevel_bus_type;
|
||||
astribank->parent = &toplevel_device;
|
||||
astribank->parent = xbus->transport.transport_device;
|
||||
dev_set_name(astribank, "xbus-%02d", xbus->num);
|
||||
dev_set_drvdata(astribank, xbus);
|
||||
astribank->release = astribank_release;
|
||||
@@ -981,16 +990,10 @@ int __init xpp_driver_init(void)
|
||||
int ret;
|
||||
|
||||
DBG(DEVICES, "SYSFS\n");
|
||||
dev_set_name(&toplevel_device, "astribanks");
|
||||
ret = device_register(&toplevel_device);
|
||||
if (ret) {
|
||||
ERR("%s: toplevel device_register failed: %d\n", __func__, ret);
|
||||
goto failed_toplevel;
|
||||
}
|
||||
if((ret = bus_register(&toplevel_bus_type)) < 0) {
|
||||
ERR("%s: bus_register(%s) failed. Error number %d",
|
||||
__FUNCTION__, toplevel_bus_type.name, ret);
|
||||
goto failed_bus;
|
||||
goto failed_toplevel;
|
||||
}
|
||||
if((ret = driver_register(&xpp_driver)) < 0) {
|
||||
ERR("%s: driver_register(%s) failed. Error number %d",
|
||||
@@ -1007,8 +1010,6 @@ failed_xpd_bus:
|
||||
driver_unregister(&xpp_driver);
|
||||
failed_xpp_driver:
|
||||
bus_unregister(&toplevel_bus_type);
|
||||
failed_bus:
|
||||
device_unregister(&toplevel_device);
|
||||
failed_toplevel:
|
||||
return ret;
|
||||
}
|
||||
@@ -1019,7 +1020,6 @@ void xpp_driver_exit(void)
|
||||
bus_unregister(&xpd_type);
|
||||
driver_unregister(&xpp_driver);
|
||||
bus_unregister(&toplevel_bus_type);
|
||||
device_unregister(&toplevel_device);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(xpd_driver_register);
|
||||
|
||||
@@ -49,6 +49,7 @@ typedef unsigned gfp_t; /* Added in 2.6.14 */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)
|
||||
/*
|
||||
* FIXME: Kludge for 2.6.19
|
||||
* bool is now defined as a proper boolean type (gcc _Bool)
|
||||
@@ -58,6 +59,12 @@ typedef unsigned gfp_t; /* Added in 2.6.14 */
|
||||
int name = init; \
|
||||
module_param(name, bool, perm); \
|
||||
MODULE_PARM_DESC(name, desc " [default " #init "]")
|
||||
#else
|
||||
#define DEF_PARM_BOOL(name, init, perm, desc) \
|
||||
bool name = init; \
|
||||
module_param(name, bool, perm); \
|
||||
MODULE_PARM_DESC(name, desc " [default " #init "]")
|
||||
#endif
|
||||
|
||||
#define DEF_PARM(type,name,init,perm,desc) \
|
||||
type name = init; \
|
||||
|
||||
@@ -57,7 +57,6 @@ struct proc_dir_entry *xpp_proc_toplevel = NULL;
|
||||
#define DELAY_UNTIL_DIALTONE 3000
|
||||
|
||||
DEF_PARM(int, debug, 0, 0644, "Print DBG statements");
|
||||
static DEF_PARM_BOOL(dahdi_autoreg, 0, 0644, "Register spans automatically (1) or not (0)");
|
||||
static DEF_PARM_BOOL(prefmaster, 0, 0644, "Do we want to be dahdi preferred sync master");
|
||||
// DEF_ARRAY(int, pcmtx, 4, 0, "Forced PCM values to transmit");
|
||||
|
||||
@@ -253,13 +252,6 @@ int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xpd_post_init(xpd_t *xpd)
|
||||
{
|
||||
XPD_DBG(DEVICES, xpd, "\n");
|
||||
if(dahdi_autoreg)
|
||||
dahdi_register_xpd(xpd);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
/**
|
||||
@@ -568,46 +560,6 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try our best to make asterisk close all channels related to
|
||||
* this Astribank:
|
||||
* - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans.
|
||||
* - Notify dahdi afterwards about spans (so it can see all changes at once).
|
||||
* - Also send DAHDI_EVENT_REMOVED on all channels.
|
||||
*/
|
||||
void xbus_request_removal(xbus_t *xbus)
|
||||
{
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
if(xpd) {
|
||||
XPD_DBG(DEVICES, xpd, "\n");
|
||||
spin_lock_irqsave(&xpd->lock, flags);
|
||||
xpd->card_present = 0;
|
||||
xpd_setstate(xpd, XPD_STATE_NOHW);
|
||||
PHONEDEV(xpd).span.alarms = DAHDI_ALARM_NOTOPEN;
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
}
|
||||
}
|
||||
/* Now notify dahdi */
|
||||
for(i = 0; i < MAX_XPDS; i++) {
|
||||
xpd_t *xpd = xpd_of(xbus, i);
|
||||
if(xpd) {
|
||||
if(SPAN_REGISTERED(xpd)) {
|
||||
int j;
|
||||
|
||||
dahdi_alarm_notify(&PHONEDEV(xpd).span);
|
||||
XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n");
|
||||
for (j=0; j<PHONEDEV(xpd).span.channels; j++) {
|
||||
dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The xpd isn't open by anyone, we can unregister it and free it
|
||||
*/
|
||||
@@ -615,7 +567,6 @@ void xpd_remove(xpd_t *xpd)
|
||||
{
|
||||
BUG_ON(!xpd);
|
||||
XPD_INFO(xpd, "Remove\n");
|
||||
dahdi_unregister_xpd(xpd);
|
||||
CALL_XMETHOD(card_remove, xpd);
|
||||
xpd_free(xpd);
|
||||
}
|
||||
@@ -734,7 +685,6 @@ int xpp_open(struct dahdi_chan *chan)
|
||||
return -EINVAL;
|
||||
}
|
||||
xpd = chan->pvt;
|
||||
xpd = get_xpd(__FUNCTION__, xpd); /* Returned in xpp_close() */
|
||||
if (!xpd) {
|
||||
NOTICE("open called on a chan with no pvt (xpd)\n");
|
||||
BUG();
|
||||
@@ -747,7 +697,6 @@ int xpp_open(struct dahdi_chan *chan)
|
||||
pos = chan->chanpos - 1;
|
||||
if(!xpd->card_present) {
|
||||
LINE_NOTICE(xpd, pos, "Cannot open -- device not ready\n");
|
||||
put_xpd(__FUNCTION__, xpd);
|
||||
return -ENODEV;
|
||||
}
|
||||
spin_lock_irqsave(&xbus->lock, flags);
|
||||
@@ -776,7 +725,6 @@ int xpp_close(struct dahdi_chan *chan)
|
||||
current->comm, current->pid,
|
||||
atomic_read(&PHONEDEV(xpd).open_counter));
|
||||
atomic_dec(&PHONEDEV(xpd).open_counter); /* from xpp_open() */
|
||||
put_xpd(__FUNCTION__, xpd); /* from xpp_open() */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -886,7 +834,7 @@ int xpp_maint(struct dahdi_span *span, int cmd)
|
||||
* If the watchdog detects no received data, it will call the
|
||||
* watchdog routine
|
||||
*/
|
||||
static int xpp_watchdog(struct dahdi_span *span, int cause)
|
||||
int xpp_watchdog(struct dahdi_span *span, int cause)
|
||||
{
|
||||
static int rate_limit = 0;
|
||||
|
||||
@@ -894,6 +842,7 @@ static int xpp_watchdog(struct dahdi_span *span, int cause)
|
||||
DBG(GENERAL, "\n");
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(xpp_watchdog);
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -915,6 +864,7 @@ static void echocan_free(struct dahdi_chan *chan,
|
||||
LINE_DBG(GENERAL, xpd, pos, "mode=0x%X\n", ec->status.mode);
|
||||
CALL_EC_METHOD(ec_set, xbus, xpd, pos, 0);
|
||||
CALL_EC_METHOD(ec_update, xbus, xbus);
|
||||
put_xpd(__FUNCTION__, xpd); /* aquired in xpp_echocan_create() */
|
||||
}
|
||||
|
||||
static const struct dahdi_echocan_features xpp_ec_features = {
|
||||
@@ -937,7 +887,7 @@ const char *xpp_echocan_name(const struct dahdi_chan *chan)
|
||||
xpd = chan->pvt;
|
||||
xbus = xpd->xbus;
|
||||
pos = chan->chanpos - 1;
|
||||
LINE_DBG(GENERAL, xpd, pos, "%s:\n", __func__);
|
||||
LINE_DBG(GENERAL, xpd, pos, "\n");
|
||||
if (!ECHOOPS(xbus))
|
||||
return NULL;
|
||||
/*
|
||||
@@ -986,6 +936,7 @@ int xpp_echocan_create(struct dahdi_chan *chan,
|
||||
*ec = phonedev->ec[pos];
|
||||
(*ec)->ops = &xpp_ec_ops;
|
||||
(*ec)->features = xpp_ec_features;
|
||||
xpd = get_xpd(__FUNCTION__, xpd); /* Returned in echocan_free() */
|
||||
LINE_DBG(GENERAL, xpd, pos, "(tap=%d, param_count=%d)\n",
|
||||
ecp->tap_length, ecp->param_count);
|
||||
ret = CALL_EC_METHOD(ec_set, xbus, xpd, pos, 1);
|
||||
@@ -994,53 +945,18 @@ int xpp_echocan_create(struct dahdi_chan *chan,
|
||||
}
|
||||
EXPORT_SYMBOL(xpp_echocan_create);
|
||||
|
||||
|
||||
/**
|
||||
* Unregister an xpd from dahdi and release related resources
|
||||
* @xpd The xpd to be unregistered
|
||||
* @returns 0 on success, errno otherwise
|
||||
*
|
||||
* Checks that nobody holds an open channel.
|
||||
*
|
||||
* Called by:
|
||||
* - User action through /proc
|
||||
* - During xpd_remove()
|
||||
*/
|
||||
int dahdi_unregister_xpd(xpd_t *xpd)
|
||||
void xpp_span_assigned(struct dahdi_span *span)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct phonedev *phonedev = container_of(span, struct phonedev, span);
|
||||
xpd_t *xpd = container_of(phonedev, struct xpd, phonedev);
|
||||
|
||||
BUG_ON(!xpd);
|
||||
spin_lock_irqsave(&xpd->lock, flags);
|
||||
|
||||
if (!IS_PHONEDEV(xpd)) {
|
||||
XPD_ERR(xpd, "Not a telephony device\n");
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
return -EBADF;
|
||||
XPD_INFO(xpd, "Span assigned: %d\n", span->spanno);
|
||||
if (xpd->card_present) {
|
||||
span->alarms &= ~DAHDI_ALARM_NOTOPEN;
|
||||
dahdi_alarm_notify(&phonedev->span);
|
||||
}
|
||||
if(!SPAN_REGISTERED(xpd)) {
|
||||
XPD_NOTICE(xpd, "Already unregistered\n");
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
return -EIDRM;
|
||||
}
|
||||
update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN);
|
||||
/* We should now have only a ref from the xbus (from create_xpd()) */
|
||||
if(atomic_read(&PHONEDEV(xpd).open_counter)) {
|
||||
XPD_NOTICE(xpd, "Busy (open_counter=%d). Skipping.\n", atomic_read(&PHONEDEV(xpd).open_counter));
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
return -EBUSY;
|
||||
}
|
||||
mdelay(2); // FIXME: This is to give chance for transmit/receiveprep to finish.
|
||||
spin_unlock_irqrestore(&xpd->lock, flags);
|
||||
if(xpd->card_present)
|
||||
CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0);
|
||||
atomic_dec(&PHONEDEV(xpd).dahdi_registered);
|
||||
atomic_dec(&num_registered_spans);
|
||||
dahdi_unregister(&PHONEDEV(xpd).span);
|
||||
if(xpd->card_present)
|
||||
CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(xpp_span_assigned);
|
||||
|
||||
static const struct dahdi_span_ops xpp_span_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -1050,6 +966,7 @@ static const struct dahdi_span_ops xpp_span_ops = {
|
||||
.maint = xpp_maint,
|
||||
.echocan_create = xpp_echocan_create,
|
||||
.echocan_name = xpp_echocan_name,
|
||||
.assigned = xpp_span_assigned,
|
||||
};
|
||||
|
||||
static const struct dahdi_span_ops xpp_rbs_span_ops = {
|
||||
@@ -1061,14 +978,54 @@ static const struct dahdi_span_ops xpp_rbs_span_ops = {
|
||||
.maint = xpp_maint,
|
||||
.echocan_create = xpp_echocan_create,
|
||||
.echocan_name = xpp_echocan_name,
|
||||
.assigned = xpp_span_assigned,
|
||||
};
|
||||
|
||||
int dahdi_register_xpd(xpd_t *xpd)
|
||||
void xpd_set_spanname(xpd_t *xpd)
|
||||
{
|
||||
struct dahdi_span *span = &PHONEDEV(xpd).span;
|
||||
|
||||
snprintf(span->name, MAX_SPANNAME, "%s/%s", xpd->xbus->busname, xpd->xpdname);
|
||||
/*
|
||||
* The "Xorcom XPD" is a prefix in one of the regexes we
|
||||
* use in our dahdi_genconf to match for PRI cards.
|
||||
* FIXME: After moving completely to sysfs, we can remove
|
||||
* this horseshit.
|
||||
*/
|
||||
snprintf(span->desc, MAX_SPANDESC, "Xorcom XPD [%s].%d: %s",
|
||||
xpd->xbus->label, span->offset + 1, xpd->type_name);
|
||||
}
|
||||
EXPORT_SYMBOL(xpd_set_spanname);
|
||||
|
||||
static void xpd_init_span(xpd_t *xpd, unsigned offset, int cn)
|
||||
{
|
||||
struct dahdi_span *span;
|
||||
int i;
|
||||
|
||||
memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span));
|
||||
for (i = 0; i < cn; i++)
|
||||
memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan));
|
||||
|
||||
span = &PHONEDEV(xpd).span;
|
||||
span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */
|
||||
span->channels = cn;
|
||||
span->chans = PHONEDEV(xpd).chans;
|
||||
|
||||
span->flags = DAHDI_FLAG_RBS;
|
||||
span->offset = offset;
|
||||
if (PHONEDEV(xpd).phoneops->card_hooksig)
|
||||
span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */
|
||||
else
|
||||
span->ops = &xpp_span_ops;
|
||||
xpd_set_spanname(xpd);
|
||||
list_add_tail(&span->device_node, &xpd->xbus->ddev->spans);
|
||||
}
|
||||
|
||||
int xpd_dahdi_preregister(xpd_t *xpd, unsigned offset)
|
||||
{
|
||||
xbus_t *xbus;
|
||||
int cn;
|
||||
int i;
|
||||
struct phonedev *phonedev;
|
||||
|
||||
BUG_ON(!xpd);
|
||||
|
||||
@@ -1078,70 +1035,26 @@ int dahdi_register_xpd(xpd_t *xpd)
|
||||
XPD_ERR(xpd, "Not a telephony device\n");
|
||||
return -EBADF;
|
||||
}
|
||||
|
||||
phonedev = &PHONEDEV(xpd);
|
||||
|
||||
if (SPAN_REGISTERED(xpd)) {
|
||||
XPD_ERR(xpd, "Already registered\n");
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
cn = PHONEDEV(xpd).channels;
|
||||
XPD_DBG(DEVICES, xpd, "Initializing span: %d channels.\n", cn);
|
||||
memset(&PHONEDEV(xpd).span, 0, sizeof(struct dahdi_span));
|
||||
for(i = 0; i < cn; i++) {
|
||||
memset(XPD_CHAN(xpd, i), 0, sizeof(struct dahdi_chan));
|
||||
}
|
||||
|
||||
span = &PHONEDEV(xpd).span;
|
||||
snprintf(span->name, MAX_SPANNAME, "%s/%s", xbus->busname, xpd->xpdname);
|
||||
span->deflaw = DAHDI_LAW_MULAW; /* default, may be overriden by card_* drivers */
|
||||
span->channels = cn;
|
||||
span->chans = PHONEDEV(xpd).chans;
|
||||
|
||||
span->flags = DAHDI_FLAG_RBS;
|
||||
if(PHONEDEV(xpd).phoneops->card_hooksig)
|
||||
span->ops = &xpp_rbs_span_ops; /* Only with RBS bits */
|
||||
else
|
||||
span->ops = &xpp_span_ops;
|
||||
|
||||
/*
|
||||
* This actually describe the dahdi_spaninfo version 3
|
||||
* A bunch of unrelated data exported via a modified ioctl()
|
||||
* What a bummer...
|
||||
*/
|
||||
span->manufacturer = "Xorcom Inc."; /* OK, that's obvious */
|
||||
/* span->spantype = "...."; set in card_dahdi_preregistration() */
|
||||
/*
|
||||
* Yes, this basically duplicates information available
|
||||
* from the description field. If some more is needed
|
||||
* why not add it there?
|
||||
* OK, let's add to the kernel more useless info.
|
||||
*/
|
||||
snprintf(span->devicetype, sizeof(span->devicetype) - 1,
|
||||
"Astribank: Unit %x Subunit %x: %s",
|
||||
XBUS_UNIT(xpd->xbus_idx), XBUS_SUBUNIT(xpd->xbus_idx),
|
||||
xpd->type_name);
|
||||
/*
|
||||
* location is the only usefull new data item.
|
||||
* For our devices it was available for ages via:
|
||||
* - The legacy "/proc/xpp/XBUS-??/summary" (CONNECTOR=...)
|
||||
* - The same info in "/proc/xpp/xbuses"
|
||||
* - The modern "/sys/bus/astribanks/devices/xbus-??/connector" attribute
|
||||
* So let's also export it via the newfangled "location" field.
|
||||
*/
|
||||
snprintf(span->location, sizeof(span->location) - 1, "%s", xbus->connector);
|
||||
/*
|
||||
* Who said a span and irq have 1-1 relationship?
|
||||
* Also exporting this low-level detail isn't too wise.
|
||||
* No irq's for you today!
|
||||
*/
|
||||
span->irq = 0;
|
||||
|
||||
snprintf(PHONEDEV(xpd).span.desc, MAX_SPANDESC, "Xorcom XPD #%02d/%1d%1d: %s",
|
||||
xbus->num, xpd->addr.unit, xpd->addr.subunit, xpd->type_name);
|
||||
XPD_DBG(GENERAL, xpd, "Registering span '%s'\n", PHONEDEV(xpd).span.desc);
|
||||
xpd_init_span(xpd, offset, cn);
|
||||
XPD_DBG(DEVICES, xpd, "Preregister local span %d: %d channels.\n",
|
||||
offset + 1, cn);
|
||||
CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 1);
|
||||
if(dahdi_register(&PHONEDEV(xpd).span, prefmaster)) {
|
||||
XPD_ERR(xpd, "Failed to dahdi_register span\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xpd_dahdi_postregister(xpd_t *xpd)
|
||||
{
|
||||
int cn;
|
||||
|
||||
atomic_inc(&num_registered_spans);
|
||||
atomic_inc(&PHONEDEV(xpd).dahdi_registered);
|
||||
CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 1);
|
||||
@@ -1161,6 +1074,43 @@ int dahdi_register_xpd(xpd_t *xpd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try our best to make asterisk close all channels related to
|
||||
* this Astribank:
|
||||
* - Set span state to DAHDI_ALARM_NOTOPEN in all relevant spans.
|
||||
* - Notify dahdi afterwards about spans (so it can see all changes at once).
|
||||
* - Also send DAHDI_EVENT_REMOVED on all channels.
|
||||
*/
|
||||
void xpd_dahdi_preunregister(xpd_t *xpd)
|
||||
{
|
||||
if (!xpd)
|
||||
return;
|
||||
XPD_DBG(DEVICES, xpd, "\n");
|
||||
update_xpd_status(xpd, DAHDI_ALARM_NOTOPEN);
|
||||
if(xpd->card_present)
|
||||
CALL_PHONE_METHOD(card_dahdi_preregistration, xpd, 0);
|
||||
/* Now notify dahdi */
|
||||
if(SPAN_REGISTERED(xpd)) {
|
||||
int j;
|
||||
|
||||
dahdi_alarm_notify(&PHONEDEV(xpd).span);
|
||||
XPD_DBG(DEVICES, xpd, "Queuing DAHDI_EVENT_REMOVED on all channels to ask user to release them\n");
|
||||
for (j=0; j<PHONEDEV(xpd).span.channels; j++) {
|
||||
dahdi_qevent_lock(XPD_CHAN(xpd, j),DAHDI_EVENT_REMOVED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void xpd_dahdi_postunregister(xpd_t *xpd)
|
||||
{
|
||||
if (!xpd)
|
||||
return;
|
||||
atomic_dec(&PHONEDEV(xpd).dahdi_registered);
|
||||
atomic_dec(&num_registered_spans);
|
||||
if(xpd->card_present)
|
||||
CALL_PHONE_METHOD(card_dahdi_postregistration, xpd, 0);
|
||||
}
|
||||
|
||||
/*------------------------- Initialization -------------------------*/
|
||||
|
||||
static void do_cleanup(void)
|
||||
@@ -1181,11 +1131,6 @@ static int __init xpp_dahdi_init(void)
|
||||
|
||||
INFO("revision %s MAX_XPDS=%d (%d*%d)\n", XPP_VERSION,
|
||||
MAX_XPDS, MAX_UNIT, MAX_SUBUNIT);
|
||||
#ifdef CONFIG_DAHDI_BRI_DCHANS
|
||||
INFO("FEATURE: with BRISTUFF support\n");
|
||||
#else
|
||||
INFO("FEATURE: without BRISTUFF support\n");
|
||||
#endif
|
||||
#ifdef CONFIG_PROC_FS
|
||||
xpp_proc_toplevel = proc_mkdir(PROC_DIR, NULL);
|
||||
if(!xpp_proc_toplevel) {
|
||||
@@ -1220,12 +1165,10 @@ static void __exit xpp_dahdi_cleanup(void)
|
||||
|
||||
EXPORT_SYMBOL(debug);
|
||||
EXPORT_SYMBOL(create_xpd);
|
||||
EXPORT_SYMBOL(xpd_post_init);
|
||||
EXPORT_SYMBOL(get_xpd);
|
||||
EXPORT_SYMBOL(put_xpd);
|
||||
EXPORT_SYMBOL(xpd_alloc);
|
||||
EXPORT_SYMBOL(xpd_free);
|
||||
EXPORT_SYMBOL(xbus_request_removal);
|
||||
EXPORT_SYMBOL(update_xpd_status);
|
||||
EXPORT_SYMBOL(oht_pcm);
|
||||
EXPORT_SYMBOL(mark_offhook);
|
||||
|
||||
@@ -25,12 +25,13 @@
|
||||
#include "xpd.h"
|
||||
#include "xproto.h"
|
||||
|
||||
int dahdi_register_xpd(xpd_t *xpd);
|
||||
int dahdi_unregister_xpd(xpd_t *xpd);
|
||||
void xbus_request_removal(xbus_t *xbus);
|
||||
void xpd_set_spanname(xpd_t *xpd);
|
||||
int xpd_dahdi_preregister(xpd_t *xpd, unsigned offset);
|
||||
int xpd_dahdi_postregister(xpd_t *xpd);
|
||||
void xpd_dahdi_preunregister(xpd_t *xpd);
|
||||
void xpd_dahdi_postunregister(xpd_t *xpd);
|
||||
int create_xpd(xbus_t *xbus, const xproto_table_t *proto_table,
|
||||
int unit, int subunit, byte type, byte subtype, int subunits, int subunit_ports, byte port_dir);
|
||||
void xpd_post_init(xpd_t *xpd);
|
||||
xpd_t *xpd_alloc(xbus_t *xbus, int unit, int subunit, int subtype, int subunits, size_t privsize, const xproto_table_t *proto_table, int channels);
|
||||
void xpd_free(xpd_t *xpd);
|
||||
void xpd_remove(xpd_t *xpd);
|
||||
@@ -46,6 +47,8 @@ int xpp_close(struct dahdi_chan *chan);
|
||||
int xpp_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long arg);
|
||||
int xpp_hooksig(struct dahdi_chan *chan, enum dahdi_txsig txsig);
|
||||
int xpp_maint(struct dahdi_span *span, int cmd);
|
||||
int xpp_watchdog(struct dahdi_span *span, int cause);
|
||||
void xpp_span_assigned(struct dahdi_span *span);
|
||||
void report_bad_ioctl(const char *msg, xpd_t *xpd, int pos, unsigned int cmd);
|
||||
int total_registered_spans(void);
|
||||
void oht_pcm(xpd_t *xpd, int pos, bool pass);
|
||||
|
||||
@@ -43,11 +43,10 @@ show_debug() {
|
||||
list=''
|
||||
for n in $dbg_names
|
||||
do
|
||||
if (( val & (1 << j) ))
|
||||
then
|
||||
if [ $(( val & (1 << j) )) -ne 0 ]; then
|
||||
list="$list $n"
|
||||
fi
|
||||
let j++
|
||||
j=$((j+1))
|
||||
done
|
||||
if [ "$list" = "" ]; then
|
||||
list=' NONE'
|
||||
@@ -67,19 +66,19 @@ calc_debug() {
|
||||
for n in $dbg_names
|
||||
do
|
||||
if [ "$wanted" = "$n" ]; then
|
||||
(( val |= (1 << j) ))
|
||||
: $(( val |= (1 << j) ))
|
||||
found=1
|
||||
elif [ "$wanted" = -"$n" ]; then
|
||||
(( val &= ~(1 << j) ))
|
||||
: $(( val &= ~(1 << j) ))
|
||||
found=1
|
||||
elif [ "$wanted" = "ANY" ]; then
|
||||
(( val = ~0 ))
|
||||
: $(( val = ~0 ))
|
||||
found=1
|
||||
elif [ "$wanted" = -"ANY" -o "$wanted" = "NONE" ]; then
|
||||
(( val = 0 ))
|
||||
val=0
|
||||
found=1
|
||||
fi
|
||||
let j++
|
||||
j=$((j+1))
|
||||
done
|
||||
if [ "$found" -eq 0 ]; then
|
||||
echo >&2 "$0: Unknown debug flag '$wanted'"
|
||||
|
||||
@@ -737,6 +737,12 @@ static int xusb_probe(struct usb_interface *interface, const struct usb_device_i
|
||||
retval = -ENOMEM;
|
||||
goto probe_failed;
|
||||
}
|
||||
snprintf(xbus->transport.model_string,
|
||||
ARRAY_SIZE(xbus->transport.model_string),
|
||||
"usb:%04x/%04x/%x",
|
||||
udev->descriptor.idVendor,
|
||||
udev->descriptor.idProduct,
|
||||
udev->descriptor.bcdDevice);
|
||||
spin_lock_irqsave(&xusb_lock, flags);
|
||||
for(i = 0; i < MAX_BUSES; i++) {
|
||||
if(xusb_array[i] == NULL)
|
||||
|
||||
@@ -75,6 +75,12 @@ static const xproto_table_t *xproto_table(xpd_type_t cardtype)
|
||||
return xprotocol_tables[cardtype];
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
|
||||
#define MODULE_REFCOUNT_FORMAT "%s refcount was %d\n"
|
||||
#else
|
||||
#define MODULE_REFCOUNT_FORMAT "%s refcount was %lu\n"
|
||||
#endif
|
||||
|
||||
const xproto_table_t *xproto_get(xpd_type_t cardtype)
|
||||
{
|
||||
const xproto_table_t *xtable;
|
||||
@@ -94,7 +100,8 @@ const xproto_table_t *xproto_get(xpd_type_t cardtype)
|
||||
if(xtable) {
|
||||
BUG_ON(!xtable->owner);
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
DBG(GENERAL, "%s refcount was %d\n", xtable->name, module_refcount(xtable->owner));
|
||||
DBG(GENERAL, MODULE_REFCOUNT_FORMAT, xtable->name,
|
||||
module_refcount(xtable->owner));
|
||||
#endif
|
||||
if(!try_module_get(xtable->owner)) {
|
||||
ERR("%s: try_module_get for %s failed.\n", __FUNCTION__, xtable->name);
|
||||
@@ -108,7 +115,8 @@ void xproto_put(const xproto_table_t *xtable)
|
||||
{
|
||||
BUG_ON(!xtable);
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
DBG(GENERAL, "%s refcount was %d\n", xtable->name, module_refcount(xtable->owner));
|
||||
DBG(GENERAL, MODULE_REFCOUNT_FORMAT, xtable->name,
|
||||
module_refcount(xtable->owner));
|
||||
BUG_ON(module_refcount(xtable->owner) <= 0);
|
||||
#endif
|
||||
module_put(xtable->owner);
|
||||
|
||||
@@ -42,7 +42,8 @@
|
||||
#include <linux/config.h>
|
||||
#endif
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#ifdef CONFIG_DAHDI_NET
|
||||
@@ -54,6 +55,8 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/interrupt.h>
|
||||
#endif
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <linux/poll.h>
|
||||
|
||||
@@ -69,6 +72,12 @@
|
||||
#define DAHDI_IRQ_HANDLER(a) static irqreturn_t a(int irq, void *dev_id, struct pt_regs *regs)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)
|
||||
#ifdef CONFIG_PCI
|
||||
#include <linux/pci-aspm.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
|
||||
#define HAVE_NET_DEVICE_OPS
|
||||
#endif
|
||||
@@ -90,16 +99,25 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)
|
||||
# ifdef RHEL_RELEASE_VERSION
|
||||
# if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5, 6)
|
||||
#define dev_name(dev) ((dev)->bus_id)
|
||||
#define dev_set_name(dev, format, ...) \
|
||||
snprintf((dev)->bus_id, BUS_ID_SIZE, format, ## __VA_ARGS__)
|
||||
# else
|
||||
#define dev_set_name(dev, format, ...) \
|
||||
do { \
|
||||
kobject_set_name(&(dev)->kobj, format, ## __VA_ARGS__); \
|
||||
snprintf((dev)->bus_id, BUS_ID_SIZE, \
|
||||
kobject_name(&(dev)->kobj)); \
|
||||
} while (0)
|
||||
# endif
|
||||
# else
|
||||
#define dev_name(dev) ((dev)->bus_id)
|
||||
# endif
|
||||
#define dev_set_name(dev, format, ...) \
|
||||
snprintf((dev)->bus_id, BUS_ID_SIZE, format, ## __VA_ARGS__);
|
||||
snprintf((dev)->bus_id, BUS_ID_SIZE, format, ## __VA_ARGS__)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*! Default chunk size for conferences and such -- static right now, might make
|
||||
@@ -885,6 +903,38 @@ struct dahdi_span_ops {
|
||||
|
||||
/*! Opt: Provide the name of the echo canceller on a channel */
|
||||
const char *(*echocan_name)(const struct dahdi_chan *chan);
|
||||
|
||||
/*! When using "pinned_spans", this function is called back when this
|
||||
* span has been assigned with the system. */
|
||||
void (*assigned)(struct dahdi_span *span);
|
||||
|
||||
/*! Called when the spantype / linemode is changed before the span is
|
||||
* assigned a number. */
|
||||
int (*set_spantype)(struct dahdi_span *span, const char *spantype);
|
||||
};
|
||||
|
||||
/**
|
||||
* dahdi_device - Represents a device that can contain one or more spans.
|
||||
*
|
||||
* @spans: List of child spans.
|
||||
* @manufacturer: Device manufacturer.
|
||||
* @location: The location of this device. This should not change if
|
||||
* the device is replaced (e.g: in the same PCI slot)
|
||||
* @hardware_id: The hardware_id of this device (NULL for devices without
|
||||
* a hardware_id). This should not change if the device is
|
||||
* relocated to a different location (e.g: different PCI slot)
|
||||
* @devicetype: What type of device this is.
|
||||
* @irqmisses: Count of "interrupt misses" for this device.
|
||||
*
|
||||
*/
|
||||
struct dahdi_device {
|
||||
struct list_head spans;
|
||||
const char *manufacturer;
|
||||
const char *location;
|
||||
const char *hardware_id;
|
||||
const char *devicetype;
|
||||
struct device dev;
|
||||
unsigned int irqmisses;
|
||||
};
|
||||
|
||||
struct dahdi_span {
|
||||
@@ -892,14 +942,10 @@ struct dahdi_span {
|
||||
char name[40]; /*!< Span name */
|
||||
char desc[80]; /*!< Span description */
|
||||
const char *spantype; /*!< span type in text form */
|
||||
const char *manufacturer; /*!< span's device manufacturer */
|
||||
char devicetype[80]; /*!< span's device type */
|
||||
char location[40]; /*!< span device's location in system */
|
||||
int deflaw; /*!< Default law (DAHDI_MULAW or DAHDI_ALAW) */
|
||||
int alarms; /*!< Pending alarms on span */
|
||||
unsigned long flags;
|
||||
u8 cannot_provide_timing:1;
|
||||
int irq; /*!< IRQ for this span's hardware */
|
||||
int lbo; /*!< Span Line-Buildout */
|
||||
int lineconfig; /*!< Span line configuration */
|
||||
int linecompat; /*!< Span line compatibility (0 for
|
||||
@@ -913,7 +959,6 @@ struct dahdi_span {
|
||||
int maintstat; /*!< Maintenance state */
|
||||
int mainttimer; /*!< Maintenance timer */
|
||||
|
||||
int irqmisses; /*!< Interrupt misses */
|
||||
int timingslips; /*!< Clock slips */
|
||||
|
||||
struct dahdi_chan **chans; /*!< Member channel structures */
|
||||
@@ -933,7 +978,11 @@ struct dahdi_span {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
struct proc_dir_entry *proc_entry;
|
||||
#endif
|
||||
struct list_head node;
|
||||
struct list_head spans_node;
|
||||
|
||||
struct dahdi_device *parent;
|
||||
struct list_head device_node;
|
||||
struct device *span_device;
|
||||
};
|
||||
|
||||
struct dahdi_transcoder_channel {
|
||||
@@ -950,6 +999,8 @@ struct dahdi_transcoder_channel {
|
||||
u32 srcfmt;
|
||||
};
|
||||
|
||||
int dahdi_is_sync_master(const struct dahdi_span *span);
|
||||
|
||||
static inline int
|
||||
dahdi_tc_is_built(struct dahdi_transcoder_channel *dtc) {
|
||||
return test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags);
|
||||
@@ -1031,6 +1082,7 @@ struct dahdi_dynamic {
|
||||
long rxjif;
|
||||
unsigned short txcnt;
|
||||
unsigned short rxcnt;
|
||||
struct dahdi_device *ddev;
|
||||
struct dahdi_span span;
|
||||
struct dahdi_chan *chans[256];
|
||||
struct dahdi_dynamic_driver *driver;
|
||||
@@ -1038,6 +1090,7 @@ struct dahdi_dynamic {
|
||||
int timing;
|
||||
int master;
|
||||
unsigned char *msgbuf;
|
||||
struct device *dev;
|
||||
|
||||
struct list_head list;
|
||||
};
|
||||
@@ -1063,6 +1116,9 @@ struct dahdi_dynamic_driver {
|
||||
|
||||
struct list_head list;
|
||||
struct module *owner;
|
||||
|
||||
/*! Numberic id of next device created by this driver. */
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
/*! \brief Receive a dynamic span message */
|
||||
@@ -1101,6 +1157,22 @@ static inline int dahdi_transmit(struct dahdi_span *span)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int dahdi_is_digital_span(const struct dahdi_span *s)
|
||||
{
|
||||
return (s->linecompat > 0);
|
||||
}
|
||||
|
||||
static inline int dahdi_is_t1_span(const struct dahdi_span *s)
|
||||
{
|
||||
return (s->linecompat & (DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF |
|
||||
DAHDI_CONFIG_B8ZS)) > 0;
|
||||
}
|
||||
|
||||
static inline int dahdi_is_e1_span(const struct dahdi_span *s)
|
||||
{
|
||||
return dahdi_is_digital_span(s) && !dahdi_is_t1_span(s);
|
||||
}
|
||||
|
||||
/*! Abort the buffer currently being receive with event "event" */
|
||||
void dahdi_hdlc_abort(struct dahdi_chan *ss, int event);
|
||||
|
||||
@@ -1115,10 +1187,12 @@ void dahdi_hdlc_putbuf(struct dahdi_chan *ss, unsigned char *rxb, int bytes);
|
||||
* and 1 if the currently transmitted message is now done */
|
||||
int dahdi_hdlc_getbuf(struct dahdi_chan *ss, unsigned char *bufptr, unsigned int *size);
|
||||
|
||||
|
||||
/*! Register a span. Returns 0 on success, -1 on failure. Pref-master is non-zero if
|
||||
we should have preference in being the master device */
|
||||
int dahdi_register(struct dahdi_span *span, int prefmaster);
|
||||
/*! Register a device. Returns 0 on success, -1 on failure. */
|
||||
struct dahdi_device *dahdi_create_device(void);
|
||||
int dahdi_register_device(struct dahdi_device *ddev, struct device *parent);
|
||||
void dahdi_unregister_device(struct dahdi_device *ddev);
|
||||
void dahdi_free_device(struct dahdi_device *ddev);
|
||||
void dahdi_init_span(struct dahdi_span *span);
|
||||
|
||||
/*! Allocate / free memory for a transcoder */
|
||||
struct dahdi_transcoder *dahdi_transcoder_alloc(int numchans);
|
||||
@@ -1133,9 +1207,6 @@ int dahdi_transcoder_unregister(struct dahdi_transcoder *tc);
|
||||
/*! \brief Alert a transcoder */
|
||||
int dahdi_transcoder_alert(struct dahdi_transcoder_channel *ztc);
|
||||
|
||||
/*! \brief Unregister a span */
|
||||
int dahdi_unregister(struct dahdi_span *span);
|
||||
|
||||
/*! \brief Gives a name to an LBO */
|
||||
const char *dahdi_lboname(int lbo);
|
||||
|
||||
@@ -1209,8 +1280,13 @@ extern u_char __dahdi_lin2mu[16384];
|
||||
extern u_char __dahdi_lin2a[16384];
|
||||
#endif
|
||||
|
||||
struct dahdi_dynamic_ops {
|
||||
struct module *owner;
|
||||
int (*ioctl)(unsigned int cmd, unsigned long data);
|
||||
};
|
||||
|
||||
/*! \brief Used by dynamic DAHDI -- don't use directly */
|
||||
void dahdi_set_dynamic_ioctl(int (*func)(unsigned int cmd, unsigned long data));
|
||||
void dahdi_set_dynamic_ops(const struct dahdi_dynamic_ops *ops);
|
||||
|
||||
/*! \brief Used by DAHDI HPEC module -- don't use directly */
|
||||
void dahdi_set_hpec_ioctl(int (*func)(unsigned int cmd, unsigned long data));
|
||||
@@ -1329,6 +1405,16 @@ static inline short dahdi_txtone_nextsample(struct dahdi_chan *ss)
|
||||
#define fatal_signal_pending(p) \
|
||||
(signal_pending((p)) && sigismember(&(p)->pending.signal, SIGKILL))
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
#ifndef PCIE_LINK_STATE_L0S
|
||||
#define PCIE_LINK_STATE_L0S 1
|
||||
#define PCIE_LINK_STATE_L1 2
|
||||
#define PCIE_LINK_STATE_CLKPM 4
|
||||
#endif
|
||||
#define pci_disable_link_state dahdi_pci_disable_link_state
|
||||
void dahdi_pci_disable_link_state(struct pci_dev *pdev, int state);
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
|
||||
|
||||
#ifndef __packed
|
||||
@@ -1356,46 +1442,15 @@ static inline int strcasecmp(const char *s1, const char *s2)
|
||||
return c1 - c2;
|
||||
}
|
||||
#endif /* clamp_val */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
static inline void list_replace(struct list_head *old, struct list_head *new)
|
||||
{
|
||||
new->next = old->next;
|
||||
new->next->prev = new;
|
||||
new->prev = old->prev;
|
||||
new->prev->next = new;
|
||||
}
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
|
||||
#define kzalloc(a, b) kcalloc(1, a, b)
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
|
||||
#define synchronize_rcu() synchronize_kernel()
|
||||
#define kasprintf dahdi_kasprintf
|
||||
char *dahdi_kasprintf(gfp_t gfp, const char *fmt, ...);
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
|
||||
#if !defined(HAVE_WAIT_FOR_COMPLETION_TIMEOUT)
|
||||
static inline unsigned long
|
||||
wait_for_completion_interruptible_timeout(struct completion *x,
|
||||
unsigned long timeout)
|
||||
{
|
||||
/* There is a race condition here. If x->done is reset to 0
|
||||
* before the call to wait_for_completion after this thread wakes.
|
||||
*/
|
||||
timeout = wait_event_interruptible_timeout(x->wait, x->done, timeout);
|
||||
if (timeout)
|
||||
wait_for_completion(x);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
#endif
|
||||
typedef u32 __bitwise pm_message_t;
|
||||
#endif /* 2.6.11 */
|
||||
#endif /* 2.6.12 */
|
||||
#endif /* 2.6.14 */
|
||||
#endif /* 2.6.18 */
|
||||
#endif /* 2.6.22 */
|
||||
#endif /* 2.6.25 */
|
||||
#endif /* 2.6.26 */
|
||||
#endif /* 2.6.31 */
|
||||
|
||||
#ifndef CONFIG_TRACING
|
||||
#define trace_printk printk
|
||||
#endif
|
||||
|
||||
#ifndef DEFINE_SPINLOCK
|
||||
#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
|
||||
#endif
|
||||
@@ -1461,6 +1516,26 @@ struct mutex {
|
||||
#define chan_err(chan, fmt, ...) chan_printk(ERR, "", chan, fmt, \
|
||||
## __VA_ARGS__)
|
||||
|
||||
#ifndef pr_err
|
||||
#define pr_err(fmt, ...) \
|
||||
printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef pr_warning
|
||||
#define pr_warning(fmt, ...) \
|
||||
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef pr_warn
|
||||
#define pr_warn pr_warning
|
||||
#endif
|
||||
#ifndef pr_notice
|
||||
#define pr_notice(fmt, ...) \
|
||||
printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef pr_info
|
||||
#define pr_info(fmt, ...) \
|
||||
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/* The dbg_* ones use a magical variable 'debug' and the user should be
|
||||
* aware of that.
|
||||
*/
|
||||
@@ -1472,6 +1547,7 @@ struct mutex {
|
||||
* be of the form DAHDI_DBG_*
|
||||
*/
|
||||
#define DAHDI_DBG_GENERAL BIT(0)
|
||||
#define DAHDI_DBG_ASSIGN BIT(1)
|
||||
#define DAHDI_DBG_DEVICES BIT(7) /* instantiation/destruction etc. */
|
||||
#define dahdi_dbg(bits, fmt, ...) \
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && DAHDI_PRINTK(DEBUG, \
|
||||
@@ -1484,6 +1560,10 @@ struct mutex {
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && \
|
||||
chan_printk(DEBUG, "-" #bits, chan, \
|
||||
"%s: " fmt, __func__, ## __VA_ARGS__)))
|
||||
#define dahdi_dev_dbg(bits, dev, fmt, ...) \
|
||||
((void)((debug & (DAHDI_DBG_ ## bits)) && \
|
||||
dev_printk(KERN_DEBUG, dev, \
|
||||
"DBG-%s(%s): " fmt, #bits, __func__, ## __VA_ARGS__)))
|
||||
#endif /* DAHDI_PRINK_MACROS_USE_debug */
|
||||
|
||||
#endif /* _DAHDI_KERNEL_H */
|
||||
|
||||
Reference in New Issue
Block a user