Compare commits

..

66 Commits

Author SHA1 Message Date
Shaun Ruffell
41639330a5 wctdm24xxp: Eliminate chance for channel to be stuck in RED alarm.
There was a code patch where it was possible to get stuck in RED ALARM on a
channel when debouncing the battery states. The state transitions would look
like this:

BATTERY_PRESENT -> BATTERY_DEBOUNCING_LOST -> BATTERY_DEBOUNCING_LOST_ALARM --
(send alarm up to asterisk) --> BATTERY_LOST -> BATTERY_DEBOUNCING_PRESENT ->
BATTERY_DEBOUNCING_PRESENT_ALARM -> BATTERY_DEBOUNCING_LOST -> BATTERY_PRESENT

In the above sequence there was never any transition from
BATTERY_DEBOUNCING_PRESENT_ALARM to BATTERY_PRESENT so the alarm to Asterisk was
never cleared and the channel stayed stuck.

Now when you loose battery when in the BATTERY_DEBOUNCING_PRESENT_ALARM go all
the way back to the BATTERY_LOST state instead of the BATTERY_DEBOUNCING_LOST
state so that all the events are properly sent up.

This fixes a regression introduced in 2.6.0 with commit (r10169 "wctdm24xxp: Use
interval for debouncing FXO battery." 874b76bd22).

Internal-Issue-ID: DAHDI-1019
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
(cherry picked from commit 8bf0434896)
2013-01-25 13:12:59 -06:00
Shaun Ruffell
e3931e5d5f wctdm24xxp: Use framecount and not jiffies when looking for battery present.
The logic to check for battery lost and battery present were using different
time bases. One was using jiffies and the other was using framecount. Since
framecount is always in milliseconds, let's use that to stay consistent.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
(cherry picked from commit a6be603590)
2013-01-25 13:12:50 -06:00
Shaun Ruffell
33b4edf463 wcb4xxp: Allocate memory in hfc_decode_st_state() with GFP_ATOMIC.
hfc_decode_st_state() will be called from interrupt context when the debug flag
is set to 32. Therefore, must use GFP_ATOMIC when allocating memory.

Only affects the wcb4xxp driver when called with particular debug flags set.

Internal-Issue-ID: DAHLIN-314
Reported-by: Gerald Schnabel
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
(cherry picked from commit 85e6cdde83)
2013-01-25 13:10:52 -06:00
Shaun Ruffell
46cfdca5d5 wct4xxp: t4_serial_setup() was called more often than necessary.
The driver iterates through all the spans on a given device during assignment,
checking for unassigned spans, but it was erroneously testing the span on which
assigned was called.

This just removes some unexpected behavior and provides a slight performance
increase on load and does not impact the functionality of the driver as far as
I'm aware.

Reported-by: Doug Bailey <dbailey@digium.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
(cherry picked from commit 9de213b104)
2013-01-25 13:10:10 -06:00
Shaun Ruffell
42be50ca28 wct4xxp: EC channel calculation in TONEDETECT assumes TE820.
Since r10290 "wct4xxp: Add support for TE820 and VPMOCT256." [1],
the TONEDETECT ioctl was not calculating the VPM channel correctly
on non TE820 cards. This fixes a regression first introduced in
2.6.0.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10290

Internal-Issue-ID: DAHLIN-302
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10733 a0bf4364-ded3-4de4-8d8a-66a801d63aff
(cherry picked from commit abad4b4479)
2013-01-25 13:09:49 -06:00
Shaun Ruffell
f6511b1040 wctdm24xxp: Only two polarity reversals are needed to validate RING on FXO ports.
This fixes a regression introduced in commit r10186 "wctdm24xxp: Use time
interval for debouncing FXO ring detect." [1] which was first released in
DAHDI-Linux 2.6.0. This only affects users with analog trunks whose providers do
not present 4 polarity reversals on the ring signals. The reporter of this issue
is based in South Africa.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10168

In prior versions, the ring detector did not check for polarity reversals, only
the presence of ringing voltage unless fwringdetect or neonmwi_monitor mode was
set, and even when one of those modes were set, the driver only needed two
reversals to validate a ring. This commit allows the driver to always stay in
fwringdetect mode but restores the requirement for only two reversals.

Also included in this commit is a change to ensure that ringing is not reported
when debouncing lost battery which can happen when voltage is swinging through
0.

Reported-and-Tested-by: Jaco Kroon <jaco@uls.co.za>
Internal-Issue-ID: DAHLIN-298
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@10719 a0bf4364-ded3-4de4-8d8a-66a801d63aff
(cherry picked from commit 84e70cdac5)
2013-01-25 13:09:32 -06:00
Shaun Ruffell
179a48862d xpp: Do not typedef bool on RHEL 5.2 or later.
Without digging into the specifics, it looks like Red Hat Linux 5.9
removed the hex_asc definition that was previously used to determine
if the bool definition was backported.

We can simply use the RHEL_RELEASE_CODE now since we do not support any
releases before the 5 series now.

Reported-By: Vladimir Mikhelson
Internal-Issue-ID: DAHLIN-312
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
(cherry picked from commit da0aa6f231)

Conflicts:
	drivers/dahdi/xpp/xdefs.h
2013-01-25 13:08:52 -06:00
Tzafrir Cohen
f9632cdeb3 gitignore: Add README.html to git ignore list
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com>
(cherry picked from commit a8dfd61e53)
2013-01-25 13:07:15 -06:00
Tzafrir Cohen
161698087d Add .gitignore file
Allows 'git status' command to better show untracked files which one may be
interested in.

Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>
Acked-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>
(cherry picked from commit d889fb39d3)
2013-01-25 13:06:39 -06:00
Tzafrir Cohen
6262abb53c xpp: pre/post_unregister: not for the EC
Don't run the pre- and post-unregister hooks on a non-phone XPD
(practically: the echo canceller). This fixes a panic with manual
'dahdi_registertion off' as it is now called for the whole device
(regression of 2.6.x).

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10735

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10736 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-11-15 15:15:48 +00:00
Shaun Ruffell
7ad722e684 dahdi: pci-aspm.h was included in 2.6.26 not 2.6.25.
When compiling against kernels 2.6.25, you could get the following error.

  error: linux/pci-aspm.h: No such file or directory

This fixes a build regression introduced in r10556 "dahdi: Add
dahdi_pci_disable_link_state for kernel < 2.6.25." [1]

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10556

Reported-by: Jean-Philippe Lord
Internal-Issue-ID: DAHLIN-299
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10705

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10708 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-08-16 21:39:01 +00:00
Shaun Ruffell
3a3684a38e wcte12xp: Fix stack corruption when checking T1 RBS states.
This fixes an (embarrassing) error in t1_check_sigbits in the previous commit
where I was writing pass the end of an array on the stack.

Now instead of using an array on the stack, of which all elements were not used,
the pending commands are now stored on a list. I also removed the automatic free
of commands from __t1_getresults and now the function that allocated the command
now frees them.

I believe this will be less error-prone going forward.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Signed-off-by: Russ Meyerriecks <rmeyerriecks@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10700

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10707 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-08-16 21:38:57 +00:00
Shaun Ruffell
8db0c61fd8 wcte12xp: Fix pulse digit detection when set for FXO signalling modes.
The frequency that the RBS registers were polled was too slow to catch the pulse
dialing digits. The result was that often times dahdi would generate WINK events
instead of PULSEDIGIT events.

This speeds up the rate at which the registers are checked from 100ms to 33ms
and also makes the process of checking the registers quicker by queing up all
the reads at once.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10699

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10706 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-08-16 21:38:52 +00:00
Shaun Ruffell
319d51ae5d wcte12xp: Allow default_linemode to be set to j1.
To enable J1 mode previously one would configure the card in T1 mode and then
set the j1mode module parameter. Now "modprobe wcte12xp default_linemode=j1"
will work like the other linemodes globally for all cards manged by this driver.
J1 can also be set on a card-by-card basis in sysfs.

Also move pr_fmt to top of file so pr_xxx macros print the module name as
intended.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10696

Conflicts:
	drivers/dahdi/wcte12xp/base.c

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10698 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-06-23 04:36:12 +00:00
Shaun Ruffell
83090b71cf wcte12xp: Destroy the cache if the linemode is not recognized.
Fixes the following errors when running:
  # modprobe wcte12xp default_linemode=blah; modprobe wcte12xp default_linemode=blah

'blah' is an unknown span type.kmem_cache_create: duplicate cache wcte12xp

Call Trace:
 [<ffffffff800394cf>] kmem_cache_create+0x572/0x5ac
 [<ffffffff800a926e>] __link_module+0x0/0x18
 [<ffffffff80064624>] __down_read+0x12/0x92
 [<ffffffff8002224d>] __up_read+0x19/0x7f
 [<ffffffff8818b01f>] :wcte12xp:te12xp_init+0x1f/0xde
 [<ffffffff800a9e37>] sys_init_module+0xbd/0x206
 [<ffffffff8005d28d>] tracesys+0xd5/0xe0

Reported-by: James Brown <jbrown@digium.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10695

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10697 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-06-23 04:36:08 +00:00
Oron Peled
c0eebd73bb xpp: usermode_helper() bugfix for kernels >= 3.3.0
* UMH_WAIT_PROC semantics (and value) was changed from enum to
  a bitmask (via #define)
* This constant was missing from kernels older than 2.6.23

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10694 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-06-21 17:53:33 +00:00
Doug Bailey
9aa57f62f1 Assign NULL values to pointers to insure that future kfree calls do not cause errors.
From: Doug Bailey <dbailey@digium.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10678

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10679 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-27 20:12:09 +00:00
Shaun Ruffell
79e20be476 xpp: Fix compilation when CONFIG_DAHDI_WATCHDOG is defined.
Looks like a hold over from when dahdi_span_ops was first implemented in r8985
"dahdi: Move the callbacks in dahdi_span into its own structure" [1].

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=8985
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10658

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10660 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-11 20:19:29 +00:00
Mike Sinkovsky
396f1a76b1 dahdi: Fix compilation when CONFIG_DAHDI_WATCHDOG is defined.
From: Mike Sinkovsky <msink@trikom.ru>

Internal-Issue-ID: DAHLIN-288
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10655

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10657 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-11 17:45:45 +00:00
Tzafrir Cohen
ca95a19f41 FPGA_1161.201.hex rev 10545: fix reset of XR1000
Previous commit (r10651) included an incorrect version. Including full message
from that commit for the description.

rev. 10502 of the FPGA firmware for the new E-Main rev. 4 fixes a potential
issue when used on Xorcom XR1000 systems: an issue with the power supply may
cause the unit to reset.

Note that there is no issue with previous models, with a normal setup of an
Astribank, or other XRx000 systems.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10652

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10654 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-11 09:16:06 +00:00
Tzafrir Cohen
41c3c2e879 FPGA_1161.201.hex rev 10532: fix reset of XR1000
rev. 10502 of the FPGA firmware for the new E-Main rev. 4 fixes a potential
issue when used on Xorcom XR1000 systems: an issue with the power supply may
cause the unit to reset.

Note that there is no issue with previous models, with a normal setup of an
Astribank, or other XRx000 systems.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10649

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10651 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-10 22:00:52 +00:00
Shaun Ruffell
c98b3a689e wcte12xp, wctdm24xxp, wct4xxp: Print warning about potential GPL violation w/HOTPLUG_FIRMWARE=no.
Print a warning message that it may be a GPL violation to redistribute these
binaries if the firmware for the VPMOCT032/64/128/256 is compiled in.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10646

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10648 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-05 20:34:50 +00:00
Shaun Ruffell
9deb9b2a4f wcb4xxp: Remove asm/system.h include.
Not needed anymore and will break compilation on Kernel versions >= 3.4 since
commit 0195c00244dc2e [1]

[1] http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=0195c00244dc2e

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10641

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10645 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-05 16:22:41 +00:00
Shaun Ruffell
0a92282cfe dahdi_dummy: Include timer.h instead of time.h
It appears that some kernel configurations do not include timer.h in any of
the include files that are included by dahdi_dummy. The timer_structs are
defined in timer.h and not time.h, so this change is correct even though I
never could find a configuation myself that actually failed to compile.

This has negligible impact since dahdi_dummy is not compiled by default.

Internal-Issue-ID: DAHLIN-185
Reported-by: Steve Murphy
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10640

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10644 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-05 16:22:37 +00:00
Shaun Ruffell
3c800538f7 dahdi: Fix compilation when CONFIG_DAHDI_NET is defined.
'irq' field was removed from dahdi_span in r10276 "dahdi: Remove
dahdi_span.irq and move dahdi_span.irqmisses into dahdi_device." [1]
which was first released in dahdi-linux 2.6.0.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10276

Reported-by: Pavel Selivanov
Internal-Issue-ID: DAHLIN-278
Patches: hdlc.patch by Pavel Selivanov (license #5420)
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10634

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10637 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 22:02:31 +00:00
Shaun Ruffell
6384cb034a dahdi: Fix compilation when CONFIG_DAHDI_ECHOCAN_PROCESS_TX is defined.
'ec_state' was renamed to 'dahdi_echocan_state' in r6529 [1] but support for
CONFIG_DAHDI_ECHOCAN_PROCESS_TX was first committed in r9442 [2]. So it
appears that I never compiled tested this exact commit when it went in for the
2.5.0 release.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=6529
[2] http://svnview.digium.com/svn/dahdi?view=revision&revision=9442

Reported-by: Pavel Selivanov
Internal-Issue-ID: DAHLIN-279
Patches: ec.patch uploaded by Pavel Selivanov (License #5420)
[ edited the patch slightly for minor formatting ]
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10633

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10636 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 22:02:26 +00:00
Shaun Ruffell
0ecf2c67c8 dahdi_dynamic_loc: Change and check the dyn->pvt pointer under lock.
Fixes a crash on unload if the sync_tick callback was running at the same time
the dynamic local span was destroyed. It was possible for
dahdi_dynamic_local_transmit to dereference a pointer that may have already
been freed.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10627

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10632 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 20:10:20 +00:00
Shaun Ruffell
89ea0430df dahdi_dynamic_eth: Make ztdeth_exit() symetrical with ztdeth_init() and fix race on unload.
Minor change to follow generally recommended practice. Prevents new packets
from being queued up for devices when they are about to be cleaned up. Also
clean up any skbs that may still be on the queue after unloading.

Also closes anoter potential kernel oops on module unload. It was possible to
delete the private structure while the master span process was running. The
result was an attempt to page memory from interrupt context.

Make sure that the pvt function is set and cleared under the zlock. Also do
not assume that the pvt pointer is valid in ztdeth_transmit.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10626

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10631 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 20:10:16 +00:00
Shaun Ruffell
05bac84ce8 dahdi_dynamic: Close race on unload if red alarm timer was running when unloaded.
I saw a kernel oops that was the result of the timer running after the
dahdi_dynamic module was unloaded. Now we wait for the timer to complete, and
then delete it again in case it reactivated itself.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10625

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10630 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 20:10:12 +00:00
Shaun Ruffell
5b675ab400 dahdi_dynamic: Remove calls to __module_get().
The board drivers are the ones calling the unregister function, and
therefore we do not need to worry about them unloading while calling the
destroy callback.

When destroying spans with the ioctl, replace __module_get() with
try_module_get. This avoids hitting a BUG in module_get on kernel versions <
2.6.29.

ALSO move the call to try_module_get out of the dahdi_dynamic_release function
and into destroy. This way if the destroy callback isn't called because the
dynamic driver is unloading the dynamic device can be left on the list to be
cleaned up by the dahdi_dynamic_unregister_driver function().

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10624

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10629 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 20:10:08 +00:00
Shaun Ruffell
69774cd457 dahdi_dynamic: Do not call into dahdi_dynamic without holding reference.
Instead of registering a function pointer, register a dahdi_dynamic_ops
structure that contains the owner as well as the ioctl callback. This way
dahdi.ko can bump up the reference count on dahdi_dynamic.ko before calling
the ioctl callback.

Also, use the registration mutex to guard against the module being unloaded
between the time the structure pointer was checked, and the module reference
is taken.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10623

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10628 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-03 20:10:03 +00:00
Shaun Ruffell
9dde3cff9c wctdm24xxp, wcte12xp: Allow VPMOCT032 firmware to be compiled into driver.
Enables the driver to update firmware on systems that do not have the firmware
loader configured / enabled (Linux config option CONFIG_FW_LOADER). Compiling
the firmware into the driver increase the memory footprint by around ~440K.

Internal-Issue-ID: DAHDI-963
Reported-and-Tested-by: Guenther Kelleter
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10618

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10620 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-04-02 14:05:17 +00:00
Shaun Ruffell
e15edb0d7a wctdm24xxp: Remove forward declaration of inline for GCC 3.4.4
GCC 3.4.4 does not allow forward declaration of inline functions.

Internal-Issue-ID: DAHLIN-286
Reported-by: Guenther Kelleter
Patches: wctdm24xxp-inline.patch uploaded by Guenther Kelleter (License #6372)
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10613

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10614 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-29 15:28:43 +00:00
Shaun Ruffell
848d5ae115 wct4xxp: Trivial formatting changes around request_irq.
Quiet some checkpatch warnings introduced by the last patch. I kept this
separate since it may have obscured the real change made in the previous
commit if combined.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10590

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10594 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-22 18:36:14 +00:00
Shaun Ruffell
fa86c13c3b wct4xxp: Disable all interrupts explicitly in interrupt handler.
The driver makes the assumption that interrupts are disabled but this cannot
be guaranteed. We'll explicity disable interrupts on the local processor while
the interrupt handler is running.

This eliminates the "IRQF_DISABLED is not guaranteed on shared IRQs" warning
when loading the driver.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10589

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10593 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-22 18:36:10 +00:00
Shaun Ruffell
bad3860f24 dahdi_dynamic_eth: Fix compilation on kernels < 2.6.22.
Resolves the follwing build error:
  drivers/dahdi/dahdi_dynamic_eth.c: In function ‘ztdeth_exit’:
  drivers/dahdi/dahdi_dynamic_eth.c:448: error: implicit declaration of function ‘cancel_work_sync’

RHEL kernel versions 2.6.18-238 (5.6) and greater had cancel_work_sync()
backported which is what I did my original smoke test on.

Reported-by: Oron Peled <oron.peled@xorcom.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10588

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10592 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-22 18:36:06 +00:00
Shaun Ruffell
5fcf13fdef dahdi_dynamic_eth: Prevent crash is packet arrives before span is fully configured.
It was possible after a dynamic ethernet span was created for a packet to come
in before the dahdi_span was fully initialized. The result would be a NULL
pointer dereference. Now just discard any packets that might come in during
this time window.

Internal-Issue-ID: DAHLIN-280
Reported-by: Pavel Selivanov
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10587

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10591 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-22 18:36:01 +00:00
Oron Peled
7c99a670b5 xpp: FXS: added a 'lower_ringing_noise' parameter
* Adds a new parameter, 'lower_ringing_noise', to module xpd_fxs.

* Makes the "power-down" behaviour that was added
  in upstream svn r10478, switchable in runtime.

* By default (false), makes the vbat_h behave like it did
  before the power-down change.
  - I.e: vbat_h is held throughout the ringing period (during
    both ring-up/ring-down)
  - So this patch revert part of r10478

* When switched to true, activate the "power-down" behaviour.
  - I.e: vbat_h follows the ring-up/ring-down.
  - This behaviour lowers the noise caused by group ringing of
    FXS channels in the same unit, but causes problems with CallerID.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10574

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10576 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 20:35:33 +00:00
Oron Peled
91a94133f1 xpp: FXS: atomic vbat_h power handling
* In do_chan_power() make vbat_h changes atomic.
* As a result we can ignore duplicate requests.
  This will allow cleaner logic in the next commit.
* Added proper debug messages.

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10573

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10575 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 20:34:05 +00:00
Oron Peled
4f487f8d7d remove a duplicate dev_set_name()
Remove duplicate definition from dahdi-sysfs.c

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10447

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10572 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:36:32 +00:00
Shaun Ruffell
77437503a8 dahdi_dynamic: Since dynamic devices are 'parentless' we must name them.
This in conjunction with r10449 "A parent-less device should not crash dahdi",
this allows dahdi_dynamic spans to work post the dahdi_devices changes in
2.6.0.

The full address of the device is not used since kernels prior to 2.6.31 limit
the length of a devicename to 20 characters.  The full address of the device
can be pulled out of the "hardware_id" and "type" fields of the span.

This patch is just to get things working again. dahdi_dynamic devices *may*
still have issues if the auto_assign_spans module parameter is 0.

Internal-Issue-ID: DAHLIN-280
Reported-by: Pavel Selivanov
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10563

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10571 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:12:10 +00:00
Shaun Ruffell
8297239209 dahdi_dynamic_eth: Move tx packet flushing to process context.
The masterspan can be, and often is, called with interrupts disabled but
dev_queue_xmit() needs to be called with interrupts enabled. This potentially
fixes a deadlock.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10562

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10570 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:12:08 +00:00
Shaun Ruffell
28d13b909c dahdi: Update dev_set_name / dev_name for RHEL 5.6+.
This is needed because dev_name() is mapped to kobject_name() in a backport,
but the kobject name isn't set until after device_add().  The result would be
parentless devices would fail since dahdi would not think a name was set for
these devices.

For these systems, we'll set both the bus_id string and the underlying
kobject_name.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10561

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10569 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:12:06 +00:00
Oron Peled
52b56c9848 A parent-less device should not crash dahdi
* A parent-less device should not crash dahdi:
  - Access span->parent->dev instead of span->parent-dev.parent
    in soem cases.
  - Access span->parent->dev via new inline span_device()
  - Use span_device() in all dahdi_dev_{dbg,info}()

* Allow low-level drivers to set their device name.
  - Drivers that don't use this feature get the default name
    based on the parent device name
  - Parent-less devices which don't set their name, fails
    to register with -EINVAL

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10449

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10568 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:12:02 +00:00
Shaun Ruffell
eff796fd8f wcte12xp, wctdm24xxp: Add compile-time option to disable ASPM for PCIe devices.
Certain BIOSes appear to enable ASPM even though it is not fully supported by
the platform. Also, since the PCIe links for TDM cards are always in use it
does not make sense to allow them to transition to the disabled state.

Just turn off power management on the PCIe links completely. For more
information see http://lwn.net/Articles/449448/.

Internal-Issue-ID: DAHLIN-283
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10557

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10567 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:11:57 +00:00
Shaun Ruffell
00ef2bfa13 wct4xxp: Add compile-time option to disable ASPM for PCIe devices.
Certain BIOSes appear to enable ASPM even though it is not fully supported by
the platform. Also, since the PCIe links for TDM cards are always in use it
does not make sense to allow them to transition to the disabled state.

Just turn off power management on the PCIe links completely. For more
information see http://lwn.net/Articles/449448/.

Internal-Issue-ID: DAHLIN-283
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10558

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10566 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:11:53 +00:00
Shaun Ruffell
a2bfd1d4c2 wct4xxp: __t4_frame_in and __t4_framer_out slowdowns.
This is a partial revert of r10234 "wct4xxp: __t4_framer_in and
__t4_framer_out speedups."

There were some platform + firmware version combinations that would fail to
properly configure the framer with the aforementioned speedups. The originally
reported sympton was that interrupts would fail to start and while
troubleshooting I also saw cases where one of the spans would stay in alarm
after starting. By adding in additional reads to the version register, the
overall process of writing / reading from the framer control registers is
slowed down which increases reliability.

This change does *not* affect the main path of TDM data which is DMAed
directly into buffers in host memory and are not read / written to / from
framer registers directly.

Reported-and-Tested-by: Vahan Yerkanian <vahan@arminco.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10559

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10565 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:11:49 +00:00
Shaun Ruffell
6009f56f8b dahdi: Add dahdi_pci_disable_link_state for kernel < 2.6.25.
Will allow the ASPM (Active State Power Management) state to be disabled on
PCIe devices before kernel version 2.6.25.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10556

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10564 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-21 19:11:44 +00:00
Tzafrir Cohen
7a497cee43 xpp: firmwares: useless 0x1A at EOF
Remove a mostly harmless 0x1A (^Z) at the end of the file. If you
add a NL after it, it breaks the firmware loading.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10550

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10553 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-20 11:20:36 +00:00
Tzafrir Cohen
853b69a106 xpp: firmwares to support E-Main 4
USB firmware (USB_FW.201.hex 10402) and FPGA firmware
(FPGA_1161.201.hex 10480) with support of the new E-Main 4 Astribank
mainboard.

(This was accidentally labeled as 'E-Main 3' in some previous commit
messages)

Also includes Makefile fixes from r10536.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10535

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10538 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-18 19:00:04 +00:00
Tzafrir Cohen
adfcd9d864 xpp: USB_FW rev 10401: minor 6FXS/2FXO caps issue
Fixes an issues with the 6FXS/2FXO module: if an extra FXS or FXO module
is added to a system with such a module, an excessive number of port
licenses was accidentally required (as if the 6FXS/2FXO module required
8FXS/8FXO licenses).

Internal-Issue-ID: #1371
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10534

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10537 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-18 18:57:51 +00:00
Shaun Ruffell
2b2054f28b dahdi_dummy: Fix compilation since dahdi-linux 2.6.0.
Even though dahdi_dummy is no longer built by default, the adoption of
dahdi_devices in 2.6 broke the ability to compile. This was not intended as
there are some packagers who still patch the Kbuild file to enable
dahdi_dummy.

Internal-Issue-ID: DAHLIN-274
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10486

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10526 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-16 16:11:29 +00:00
Shaun Ruffell
6e1058eae0 xpp: '%d' -> '%lu' when displaying module_refcount on kernel versions >= 3.3
Upstream commit bd77c047 "module: struct module_ref should contains long
fields" changed the return of module_refcount from int to unsigned long. This
change eliminates a warning from the string format specifier.

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10485

Conflicts:

	drivers/dahdi/xpp/xproto.c

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10525 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-16 16:11:25 +00:00
Shaun Ruffell
8067ae3269 xpp: Use 'bool' type for boolean module parameters on kernel versions >= 2.6.31.
Eliminates warnings that are a result of upstream commit 72db395ffa
"module_param: check that bool parameters really are bool."

Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10484

Conflicts:

	drivers/dahdi/xpp/xpd.h

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10524 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-16 16:11:20 +00:00
Oron Peled
54b9983407 xpp: FXS: better power-down to lower noise
* Now every linefeed control command which is not RING'ing
  powers-down the SLIC. This reduce audible noise when
  several channels are ringing.

* Simplify code by removing redundant calls to do_chan_power()
  before linefeed_control()

* Manage vbat_h state so we skip do_chan_power() calls when
  there isn't a state change

* Export vbat_h state to /proc/.../fxs_info

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10478

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10490 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-15 17:36:48 +00:00
Oron Peled
b4989839bc xpp: reset Astribank SPI busses
* A driver reload should reset Astribank hardware
* This patch send an SPI reset after we get AB_DESCRIPTION reply from Astribank

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10474

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10489 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-15 17:35:57 +00:00
Shaun Ruffell
3876f253a6 wctdm24xxp: Shorten RINGOFF debounce interval from 512ms to 128ms.
In commit r10168 "wctdm24xxp: Use time interval for debouncing FXO ring
detect" [1], I inadvertently changed the debounce interval of the RINGOFF
event from 128ms to 512ms. The result was a potential failure to detect CID,
depending on line conditions, since Asterisk would bump the rx gains on the
channel in the middle of the CID spill as opposed to before the CID spill.

This fixes a regression first introduced in DAHDI-Linux 2.6.0.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10168

Internal-Issue-ID: DAHDI-951
Reported-and-Tested-by: Jack Wilson <ljwilson@digitalav.com>
Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10473

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10481 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-03-15 15:03:27 +00:00
Tzafrir Cohen
005aa723ef USB_RECOV.hex: recovering from xpp hardware issues
USB_RECOV.hex, rev. 9760. It may be used to recover from certain
issues of the USB controller of the Astribank (when an Astribank
is not detected as such) by Support staff.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10455

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10457 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-02-07 22:19:39 +00:00
Tzafrir Cohen
808b2dd408 Astribank I firmwares rev. 7107
A slightly newer firmware (Xorcom rev. 7107) for older (non Astribank
II) Astribank modules. Was accidentally left uncommited. Includes minor
bug fixes.

No change for any relatively recent (Astribank II) Astribank.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10443

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10445 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-25 20:51:21 +00:00
Tzafrir Cohen
081977bc94 Build OSLEC EC if in the tree
Build the OSLEC echo canceller (drivers/staging/echo and
dahdi_echocan_oslec) if the code of oslec is present in the tree.

Also closing another issue regarding documentation of building OSLEC,
as it is now even clearer than before.

Patch has been used in the Debian package for quite some time.

Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

(closes issue DAHLIN-110)
Reported by: biohumanoid (Pavel Selivanov)
Patches:
     oslec_auto.diff uploaded by tzafrir (license 5035)

(closes issue DAHLIN-261)

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10440

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10442 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-17 14:50:01 +00:00
Oron Peled
f06c8d50cf xpp: handle failures during dahdi_register_device()
* If dahdi_register_device() failed, not all resources were freed.
  When dahdi_unregister_device() was called later (during driver
  removal) a panic was caused.

* Add proper error handling for possible failures in
  xbus_register_dahdi_device():
  - new xbus_free_ddev() safely free an xbus->ddev
  - This is called from all failures points.
  - It is also called from xbus_unregister_dahdi_device()

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10410

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10419 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-10 22:09:34 +00:00
Oron Peled
17a2ce9421 xpp: Don't deactivate XPDs on unregistration
* A bug was introduced during migration to dahdi_device code:
    http://svnview.digium.com/svn/dahdi?view=rev&rev=10273
* Marking XPDs as non-functional (card_present=0, XPD_STATE_NOHW)
  was moved from xbus_request_removal() into xpd_dahdi_preunregister()
* As a result, unregistering an Astribank, made it non-functional
  so trying to re-register it later caused errors (e.g: "Cannot open"
  error message from xpp_open())
* This fix move XPD deactivation into the proper location (during
  xbus_deactivate()

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10409

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10418 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-10 22:09:29 +00:00
Oron Peled
5ed0271397 xpp: bugfix: fix bad refcount
Code path called in error condition contained an superflous put_xpd() call

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Acked-By: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10408

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10417 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-10 22:09:25 +00:00
Shaun Ruffell
48b3cb8777 wct4xxp: VPM module creates noise on alternate channels on E1 spans.
The VPMOCT128 module was using the VPMOCT256 timeslots assigments which would
mean that channels that should be marked alaw were being set in ulaw. This
only affected E1 spans since by default all spans are configured for ulaw by
default.

This fixes a regression introduced in r10290 [1] "wct4xxp: Add support for
TE820 and VPMOCT256", first released in 2.6.0, that only affects E1 spans on a
quad and dual-span card when used with the hardware echocanceler.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10290

Internal-Issue-ID: DAHDI-945, DAHLIN-275
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Acked-by: Russ Meyerriecks <rmeyerriecks@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10414

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10416 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-10 22:05:47 +00:00
Shaun Ruffell
d726b04767 wctdm24xxp: FXS on-hook transmission timer incorrect.
The DAHDI_ONHOOKTRANSFER ioctl was incorrectly setting the ohttimer to 0. The
result was that an FXS port was leaving the on-hook transfer state before
finishing the transmission.

This was discovered while looking at why ./fxstest dtmfcid  was not able to
pass the DTMF callerid digits to an attached FXO port properly.

Fixes a regression introduced in r10167 "wctdm24xxp: Use interval for checking
FXS on hook transfer timer." [1], first released in 2.6.0.

[1] http://svnview.digium.com/svn/dahdi?view=revision&revision=10167

Signed-off-by: Shaun Ruffell <sruffell@digium.com>

Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10413

git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10415 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-10 22:05:43 +00:00
Shaun Ruffell
e5ed586e31 Creating branch for 2.6.
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/branches/2.6@10406 a0bf4364-ded3-4de4-8d8a-66a801d63aff
2012-01-04 22:19:55 +00:00
116 changed files with 8734 additions and 45765 deletions

9
.gitignore vendored
View File

@@ -5,7 +5,6 @@
*.mod
*.mod.[oc]
*.ko
*.ko.unsigned
*.cmd
*.order
*.tar.gz
@@ -39,12 +38,4 @@ drivers/dahdi/firmware/dahdi-fw-oct6114-256.bin
drivers/dahdi/firmware/dahdi-fw-tc400m.bin
drivers/dahdi/firmware/dahdi-fw-te820.bin
drivers/dahdi/firmware/dahdi-fw-vpmoct032.bin
drivers/dahdi/firmware/dahdi-fw-a4a.bin
drivers/dahdi/firmware/dahdi-fw-a4b.bin
drivers/dahdi/firmware/dahdi-fw-a8a.bin
drivers/dahdi/firmware/dahdi-fw-a8b.bin
drivers/dahdi/firmware/dahdi-fw-oct6114-032.bin
drivers/dahdi/firmware/dahdi-fw-te133.bin
drivers/dahdi/firmware/dahdi-fw-te134.bin
drivers/dahdi/firmware/dahdi-fw-te435.bin
drivers/dahdi/firmware/make_firmware_object

View File

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

347
README
View File

@@ -163,24 +163,6 @@ to the script:
./build_tools/make_static_devs -d tmp/newroot/dev/dahdi
DKMS
~~~~
DKMS, Dynamic Kernel Module Support, is a framework for building Linux
kernel modules. It is used, among others, by several distributions that
package the DAHDI kernel modules.
DKMS is designed to provide updates over drivers installed from original
kernel modules tree. Thus it installed modules into /lib/modules/updates
or /lib/modules/VERSION/updates . This is generally not an issue on
normal operation. However if you try to install DAHDI from source on
a system with DAHDI installed from DKMS this way (potentially of an
older version), be sure to remove the DKMS-installed modules from the
updates directory. If you're not sure, the following command will give
you a clue of the versions installed:
find /lib/modules -name dahdi.ko
Installing the B410P drivers with mISDN
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DAHDI includes the wcb4xxp driver for the B410P, however, support for the
@@ -248,15 +230,6 @@ be reported on the
https://lists.sourceforge.net/lists/listinfo/freetel-oslec[OSLEC mailing
list].
Alternatively you can also get the OSLEC code from the dahdi-linux-extra
GIT repository:
git clone git://gitorious.org/dahdi-extra/dahdi-linux-extra.git
cd dahdi-linux-extra
git archive extra-2.6 drivers/staging | (cd ..; tar xf -)
cd ..; rm -rf dahdi-linux-extra
Live Install
~~~~~~~~~~~~
In many cases you already have DAHDI installed on your system but would
@@ -445,17 +418,54 @@ reside directly under /sys/module/'module_name' .
Useful module parameters:
=== debug
(most modules)
debug (most modules)::
Sets debug mode / debug level. With most modules 'debug' can be either
disabled (0, the default value) or enabled (any other value).
+
+
wctdm and wcte1xp print several extra debugging messages if the value
of debug is more than 1.
+
+
Some modules have "debugging flags" bits - the value of debug is a
bitmask and several messages are printed if some bits are set:
- wctdm24xxp:
* 1: DEBUG_CARD
* 2: DEBUG_ECHOCAN
- wct4xxp:
* 1: DEBUG_MAIN
* 2: DEBUG_DTMF
* 4: DEBUG_REGS
* 8: DEBUG_TSI
* 16: DEBUG_ECHOCAN
* 32: DEBUG_RBS
* 64: DEBUG_FRAMER
- xpp: See also README.Astribank:
* 1: GENERAL - General debug comments.
* 2: PCM - PCM-related messages. Tend to flood logs.
* 4: LEDS - Anything related to the LEDs status control. The driver
produces a lot of messages when the option is enabled.
* 8: SYNC - Synchronization related messages.
* 16: SIGNAL - DAHDI signalling related messages.
* 32: PROC - Messages related to the procfs interface.
* 64: REGS - Reading and writing to chip registers. Tends to flood
logs.
* 128: DEVICES - Device instantiation, destruction and such.
* 256 - COMMANDS - Protocol commands. Tends to flood logs.
Sets debug mode / debug level. With most modules 'debug' can be either
disabled (0, the default value) or enabled (any other value).
deftaps (dahdi)::
The default size for the echo canceller. The number is in "taps", that
is "samples", 1/8 ms. The default is 64 - for a tail size of 8 ms.
+
+
Asterisk's chan_dahdi tends to pass its own value anyway, with a
different default size. So normally setting this doesn't change
anything.
wctdm and wcte1xp print several extra debugging messages if the value
of debug is more than 1.
Some modules have "debugging flags" bits - the value of debug is a
bitmask and several messages are printed if some bits are set:
max_pseudo_channels (dahdi)::
The maximum number of pseudo channels that dahdi will allow userspace to
create. Pseudo channels are used when conferencing channels together.
The default is 512.
To get a list of parameters supported by a module, use
@@ -463,188 +473,13 @@ To get a list of parameters supported by a module, use
Or, for a module you have just built:
modinfo ./drivers/dahdi/module_name.ko
modinfo ./module_name.ko
For the xpp modules this will also include the description and default
value of the module. You can find a list of useful xpp module parameters
in README.Astribank .
- wctdm24xxp:
* 1: DEBUG_CARD
* 2: DEBUG_ECHOCAN
- wct4xxp:
* 1: DEBUG_MAIN
* 2: DEBUG_DTMF
* 4: DEBUG_REGS
* 8: DEBUG_TSI
* 16: DEBUG_ECHOCAN
* 32: DEBUG_RBS
* 64: DEBUG_FRAMER
- xpp: See also README.Astribank:
* 1: GENERAL - General debug comments.
* 2: PCM - PCM-related messages. Tend to flood logs.
* 4: LEDS - Anything related to the LEDs status control. The driver
produces a lot of messages when the option is enabled.
* 8: SYNC - Synchronization related messages.
* 16: SIGNAL - DAHDI signalling related messages.
* 32: PROC - Messages related to the procfs interface.
* 64: REGS - Reading and writing to chip registers. Tends to flood
logs.
* 128: DEVICES - Device instantiation, destruction and such.
* 256 - COMMANDS - Protocol commands. Tends to flood logs.
+
+
The script xpp_debug in the source tree can help settting them at run
time.
=== deftaps
(dahdi)
The default size for the echo canceller. The number is in "taps", that
is "samples", 1/8 ms. The default is 64 - for a tail size of 8 ms.
Asterisk's chan_dahdi tends to pass its own value anyway, with a
different default size. So normally setting this doesn't change
anything.
=== max_pseudo_channels
(dahdi)
The maximum number of pseudo channels that dahdi will allow userspace to
create. Pseudo channels are used when conferencing channels together.
The default is 512.
=== auto_assign_spans
(dahdi)
See <<_span_assignments,Span Assignments>> below.
XPP (Astribank) module parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
==== debug
(all modules) - see above.
==== dahdi_autoreg
(xpp)
Deprecated. See dahdi.<<_auto_assign_spans,auto_assign_spans>> above.
Originally had a somewhat similar (but xpp-specific and more limited)
role to auto_assign_spans. For backward compatibility this variable is
still kept, but its value is unused. Astribanks will auto-register
with dahdi if auto_assign_spans is not set.
==== tools_rootdir
(xpp)
Defaults to /. Passed (as the variable DAHDI_TOOLS_ROOTDIR) to generated
events (which can be used in udev hooks). Also serves as the base of
the variable DAHDI_INIT_DIR (by default: $DAHDI_TOOLS_DIR/usr/share/dahdi).
==== initdir
(xpp)
Deprecated. Setting both initdir and tools_rootdir will generate an error.
A directory under tools_rootdir containing the initialization scripts.
The default is /usr/share/dahdi .
Setting this value could be useful if that location is inconvenient for you.
==== rx_tasklet
(xpp)
Enable (1) or disable (0) doing most of the packets processing in
separate tasklets. This should probably help on higher-end systems with
multiple Astribanks.
==== vmwi_ioctl
(xpd_fxs)
Does userspace support VMWI notification via ioctl? Default: 1 (yes).
Disable this (0) to have the driver attempt to detect the voicemail
message waiting indication status for this port from FSK messages
userspace (Asterisk) sends. Set the ports to use AC neon-lamp style
message waiting indication. The detection from the FSK messages takes
extra CPU cycles but is required with e.g. Asterisk < 1.6.0 .
Also note that in order for this parameter to take effect, it must be
set before the span is registered. This practically means that it
should be set through modprobe.d files.
See also Voicemail Indication in README.Astribank.
==== usb1
(xpp_usb)
Enable (1) or disable (0) support of USB1 devices. Disabled by default.
USB1 devices are not well-tested. It seems that they don't work at all
for Astribank BRI. Generally they should work with the current code, but
we expect the voice quality issues. Hence we would like to make it
very clear that you if you have a USB1 port (rather than a USB2 one, as
recommended) you will have to take an action to enable the device.
==== poll intervals
(various)
There are various values which the driver occasionally polls the
device for. For instance, the parameter poll_battery_interval for
xpd_fxo to poll the battery, in order to know if the telco line is
actually connected.
The value of those parameters is typically a number in milliseconds.
0 is used to disable polling. Under normal operation there should be
no reason to play with those parameters.
==== dtmf_detection
(xpd_fxs)
Enable (1) or disable (0) support of hardware DTMF detection by the
Astribank.
==== caller_id_style
(xpd_fxo)
Various types of caller ID signalling styles require knowing the PCM
even when the line is on-hook (which is usually a waste of CPU and
bandwidth). This parameter allows fine-tuning the behaviour here:
* 0 (default) - Don't pass extra PCM when on-hook.
* 1 ETSI-FSK: Wait for polarity reversal to come before a ring and
then start passing PCM until the caller ID has been passed.
* 2 ETSI-DTMF: Always pass PCM and generate a DTMF if polarity reversal is
detected before ring.
* 3 Passthrough: Always pass PCM as-is.
This parameter is read-only. It cannot be changed at run-time.
==== battery_threshold
(xpd_fxo)
Minimum voltage that shows there is battery. Defaults to 3. Normally you
should not need to change this, unless dealing with a funky PSTN
provider.
==== battery_debounce
(xpd_fxo)
Minimum interval (msec) for detection of battery off (as opposed to e.g.
a temporary power denial to signal a hangup). Defaults to 1000. As with
battery_threshold above, there's normally no need to tweak it.
==== use_polrev_firmware
(xpd_fxo)
Enable (1, default) or disable (0) support for polarity reversal
detection in the hardware. Only has effect with PIC_TYPE_2.hex rev. >=
11039 and with the initialization changes (init_card_2_30) in rev.
949aa49.
This parameter is read-only. It cannot be changed at run-time.
Internals
---------
DAHDI Device Files
@@ -656,14 +491,9 @@ or dynamically through the udev system.
* /dev/dahdi/ctl (196:0) - a general device file for various information and
control operations on the DAHDI channels.
* /dev/dahdi/chan/N/M - A device file for channel M in span N
- Both N and M are zero padded 3 digit numbers
- Both N and M start at 001
- M is chanpos - numbering relative to the current span.
* /dev/dahdi/NNN (196:NNN) - for NNN in the range 1-249. A device file for
DAHDI channel NNN. It can be used to read data from the channel
and write data to the channel. It is not generated by default but may
be generated as a symlink using udev rules.
and write data to the channel.
* /dev/dahdi/transcode (196:250) - Used to connect to a DAHDI transcoding
device.
* /dev/dahdi/timer (196:253) - Allows setting timers. Used anywhere?
@@ -897,12 +727,11 @@ to other nodes.
Class DAHDI
^^^^^^^^^^^
Under /sys/class/dadhi there exists a node for the non-channel DAHDI
device file under /dev/dahdi. The name is 'dahdi!foo' for the file
'/dev/dahdi/foo' (udev translates exclamation marks to slashes). Those
nodes are not, for the most part, proper SysFS nodes, and don't include
any interesting properties. The files in this class `ctl`, `timer`,
`channel`, `pseudo` and (if exists) `transcode`.
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
@@ -927,10 +756,6 @@ A unique hardware-level identifier (e.g. serial number), if available.
===== /sys/bus/dahdi_devices/devices/DEVICE/manufacturer
The name of the manufacturer. Freeform-string.
===== /sys/bus/dahdi_devices/devices/DEVICE/registration_time
The time at which the device registered with the DAHDI core. Example
value: "0005634136.941901429".
===== /sys/bus/dahdi_devices/devices/DEVICE/spantype
A line for each available span: <num>:<type>. This has to be provided
here as in the case of manual assignment, userspace may need to know
@@ -977,12 +802,6 @@ A free-form description of the span.
===== /sys/bus/dahdi_spans/devices/span-N/lbo
LBO setting for the channel.
===== /sys/bus/dahdi_spans/devices/span-N/lineconfig
The framing and coding of the span, for a digital span. Textual
represenation:
<B8ZS|AMI|HDB3>/<D4|ESF|CCS>[/CRC4]
===== /sys/bus/dahdi_spans/devices/span-N/local_spanno
The number of the span within the DAHDI device.
@@ -995,66 +814,6 @@ A very short type string.
===== /sys/bus/dahdi_spans/devices/span-N/syncsrc
Current sync source.
==== sys/bus/dahdi_spans/drivers/generic_lowlevel/master_span
All spans in the bus are handled by a single driver. The driver has one
non-standard attribute: master_span. printing it shows the current DAHDI
master span writing a number to it forces setting this span as the master
span.
Channels Bus
^^^^^^^^^^^^
Each DAHDI channel is represented by a node under
/sys/bus/dahdi_channels/devices with the name 'dahdi!channels!N!M'
(where N is the number of the span and M is the number of the channel
in the span - chanpos). Channels of each span also reside under the node
of the span.
Useful attributes in the channel node (All attributed listed below are
read-only):
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/alarms
List of names of the current active alarms (space separated). Normally
(no alarms) empty. Example:
RED YELLOW
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/blocksize
The block size set by userspace.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/channo
The (global) channel number.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/chanpos
The channel number within the span.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/dev
Major and minor device numbers.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/ec_factory
The name of the echo canceller to be used in the channel, if one is
configured. Example:
MG2
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/ec_state
State of the echo canceller. ACTIVE: configured and inuse. INACTIVE
otherwise.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/in_use
1 if the channel is in use (was opepend by userspace), 0 otherwise.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/name
A name string for the channel
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/sig
The signalling types set for the channel. A space-separated list of
signalling types.
===== /sys/bus/dahdi_spans/devices/span-N/dahdi!channels!N!M/sigcap
The signalling types this channel may be configured to handle. A space-
separated list of signalling types.
User-space Interface
~~~~~~~~~~~~~~~~~~~~

View File

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

40
build_tools/genudevrules Executable file
View File

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

View File

@@ -1,21 +0,0 @@
#!/bin/sh
# This is a helper script intended to be called from
# drivers/dahdi/firmware/Makefile to install the different firmware version.
FIRMWARE_PATTERN=$1
FIRMWARE_VERSION=$2
DESTDIR=$3
target="$DESTDIR/lib/firmware"
if ! test -f $target/.${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}; then
echo "Installing ${FIRMWARE_PATTERN}.bin to $target"
tar --no-same-owner -xf ${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}.tar.gz || exit 1
install -m 644 ${FIRMWARE_PATTERN}.bin $target || exit 1
rm -rf $target/.${FIRMWARE_PATTERN}-*
touch $target/.${FIRMWARE_PATTERN}-${FIRMWARE_VERSION}
# Remove the .bin file so that if the version is reverted, it will not
# be installed with a non-matching ${FIRMARE_VERSION} file.
rm ${FIRMWARE_PATTERN}.bin
else
echo "Firmware ${FIRMWARE_PATTERN}.bin is already installed with required version ${FIRMWARE_VERSION}"
fi

View File

@@ -61,7 +61,7 @@ export ASTRIBANK_HEXLOAD
# make sure Astribank initialization scripts are from our tree.
xpp_ARGS="$xpp_ARGS initdir=$FIRMWARE_DIR"
dahdi_ARGS="$dahdi_ARGS tools_rootdir=$DESTDIR"
#dahdi_ARGS="$dahdi_ARGS initdir=$FIRMWARE_DIR"
if [ "$DYNAMIC_LOC" = 'yes' ]; then
MODULES_LOAD="$MODULES_LOAD dahdi_dynamic dahdi_dynamic_loc"

View File

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

View File

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

View File

@@ -7,35 +7,10 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_DYNAMIC_ETHMF) += dahdi_dynamic_ethmf.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_TRANSCODE) += dahdi_transcode.o
ifdef CONFIG_PCI
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_OCT612X) += oct612x/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTC4XXP) += wctc4xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM24XXP) += wctdm24xxp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE12XP) += wcte12xp/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE13XP) += wcte13xp.o
wcte13xp-objs := wcte13xp-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcte13xp-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcte13xp-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTE43X) += wcte43x.o
wcte43x-objs := wcte43x-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcte43x-base.o += -I$(src)/oct612x -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcte43x-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCAXX) += wcaxx.o
wcaxx-objs := wcaxx-base.o wcxb_spi.o wcxb.o wcxb_flash.o
CFLAGS_wcaxx-base.o += -I$(src)/oct612x/ -I$(src)/oct612x/include -I$(src)/oct612x/octdeviceapi -I$(src)/oct612x/octdeviceapi/oct6100api
ifeq ($(HOTPLUG_FIRMWARE),yes)
CFLAGS_wcaxx-base.o += -DHOTPLUG_FIRMWARE
endif
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCTDM) += wctdm.o
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_VOICEBUS) += voicebus/
obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCB4XXP) += wcb4xxp/
@@ -63,7 +38,7 @@ obj-m += $(DAHDI_MODULES_EXTRA)
# well:
ifneq (,$(wildcard $(src)/../staging/echo/echo.c))
obj-m += dahdi_echocan_oslec.o
obj-m += ../staging/echo/echo.o
obj-m += ../staging/echo/
endif
CFLAGS_MODULE += -I$(DAHDI_INCLUDE) -I$(src)
@@ -102,7 +77,7 @@ CFLAGS_dahdi_dynamic_ethmf.o := -DNEW_SKB_LINEARIZE
endif
endif
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-sysfs-chan.o dahdi-version.o
dahdi-objs := dahdi-base.o dahdi-sysfs.o dahdi-version.o
###############################################################################
# Find appropriate ARCH value for VPMADT032 and HPEC binary modules

6
drivers/dahdi/Makefile Normal file
View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,46 +1,112 @@
/* dahdi-sysfs.c
*
* Copyright (C) 2011-2012, Xorcom
* Copyright (C) 2011-2012, Digium, Inc.
*
* All rights reserved.
*
*/
/*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2 as published by the
* Free Software Foundation. See the LICENSE file included with
* this program for more details.
*/
#include <linux/kernel.h>
#include <linux/version.h>
#define DAHDI_PRINK_MACROS_USE_debug
#include <dahdi/kernel.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include "dahdi.h"
#include "dahdi-sysfs.h"
/* FIXME: Move to kernel.h */
#define module_printk(level, fmt, args...) printk(level "%s: " fmt, THIS_MODULE->name, ## args)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, NULL, "%s", name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#define CLASS_DEV_CREATE(class, devt, device, name) \
device_create(class, device, devt, name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_device_create(class, NULL, devt, device, name)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_device_create(class, devt, device, name)
#else
#define CLASS_DEV_CREATE(class, devt, device, name) \
class_simple_device_add(class, devt, device, name)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#define CLASS_DEV_DESTROY(class, devt) \
device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
#define CLASS_DEV_DESTROY(class, devt) \
class_device_destroy(class, devt)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
#define CLASS_DEV_DESTROY(class, devt) \
class_simple_device_remove(devt)
#else
#define CLASS_DEV_DESTROY(class, devt) \
class_simple_device_remove(class, devt)
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
static struct class *dahdi_class = NULL;
#else
static struct class_simple *dahdi_class = NULL;
#define class_create class_simple_create
#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;
module_param(initdir, charp, 0444);
MODULE_PARM_DESC(initdir,
"deprecated, should use <tools_rootdir>/usr/share/dahdi");
static char *tools_rootdir;
module_param(tools_rootdir, charp, 0444);
MODULE_PARM_DESC(tools_rootdir,
"root directory of all tools paths (default /)");
static char *initdir = "/usr/share/dahdi";
module_param(initdir, charp, 0644);
static int span_match(struct device *dev, struct device_driver *driver)
{
@@ -52,11 +118,26 @@ 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_TOOLS_ROOTDIR=%s", tools_rootdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s/%s", tools_rootdir, \
initdir); \
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)
@@ -117,6 +198,8 @@ static int span_uevent(struct device *dev, struct kobj_uevent_env *kenv)
#endif
#endif /* OLD_HOTPLUG_SUPPORT */
#define span_attr(field, format_string) \
static BUS_ATTR_READER(field##_show, dev, buf) \
{ \
@@ -128,18 +211,11 @@ static BUS_ATTR_READER(field##_show, dev, buf) \
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(spantype_show, dev, buf)
{
struct dahdi_span *span;
span = dev_to_span(dev);
return sprintf(buf, "%s\n", dahdi_spantype2str(span->spantype));
}
static BUS_ATTR_READER(local_spanno_show, dev, buf)
{
struct dahdi_span *span;
@@ -169,8 +245,6 @@ static BUS_ATTR_READER(basechan_show, dev, buf)
struct dahdi_span *span;
span = dev_to_span(dev);
if (!span->channels)
return -ENODEV;
return sprintf(buf, "%d\n", span->chans[0]->channo);
}
@@ -182,38 +256,6 @@ static BUS_ATTR_READER(channels_show, dev, buf)
return sprintf(buf, "%d\n", span->channels);
}
static BUS_ATTR_READER(lineconfig_show, dev, buf)
{
struct dahdi_span *span;
int len = 0;
span = dev_to_span(dev);
len += lineconfig_str(span->lineconfig, buf, 20);
len += sprintf(buf + len, "\n");
return len;
}
static BUS_ATTR_READER(linecompat_show, dev, buf)
{
struct dahdi_span *span;
int bit;
int len = 0;
span = dev_to_span(dev);
for (bit = 4; bit <= 12; bit++) {
if (span->linecompat & (1 << bit)) {
const char *name = dahdi_lineconfig_bit_name(bit);
if (name)
len += sprintf(buf + len, "%s ", name);
}
}
/* chomp */
while (len > 0 && isspace(buf[len - 1]))
buf[--len] = '\0';
len += sprintf(buf + len, "\n");
return len;
}
static struct device_attribute span_dev_attrs[] = {
__ATTR_RO(name),
__ATTR_RO(desc),
@@ -226,56 +268,23 @@ static struct device_attribute span_dev_attrs[] = {
__ATTR_RO(is_sync_master),
__ATTR_RO(basechan),
__ATTR_RO(channels),
__ATTR_RO(lineconfig),
__ATTR_RO(linecompat),
__ATTR_NULL,
};
static ssize_t master_span_show(struct device_driver *driver, char *buf)
{
struct dahdi_span *s = get_master_span();
return snprintf(buf, PAGE_SIZE, "%d\n", (s) ? s->spanno : 0);
}
static ssize_t master_span_store(struct device_driver *driver, const char *buf,
size_t count)
{
int spanno;
if (sscanf(buf, "%d", &spanno) != 1) {
module_printk(KERN_ERR, "non-numeric input '%s'\n", buf);
return -EINVAL;
}
set_master_span(spanno);
return count;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
static struct driver_attribute dahdi_attrs[] = {
__ATTR(master_span, S_IRUGO | S_IWUSR, master_span_show,
master_span_store),
__ATTR_NULL,
};
#else
static DRIVER_ATTR_RW(master_span);
static struct attribute *dahdi_attrs[] = {
&driver_attr_master_span.attr,
NULL,
};
ATTRIBUTE_GROUPS(dahdi);
#endif
static struct bus_type spans_bus_type = {
.name = "dahdi_spans",
.match = span_match,
.uevent = span_uevent,
.dev_attrs = span_dev_attrs,
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
.drv_attrs = dahdi_attrs,
#ifdef OLD_HOTPLUG_SUPPORT
.hotplug = span_hotplug,
#else
.drv_groups = dahdi_groups,
.uevent = span_uevent,
#endif
.dev_attrs = span_dev_attrs,
.drv_attrs = dahdi_attrs,
};
static int span_probe(struct device *dev)
@@ -301,7 +310,9 @@ static struct device_driver dahdi_driver = {
.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)
@@ -311,7 +322,26 @@ static void span_uevent_send(struct dahdi_span *span, enum kobject_action act)
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)
@@ -319,6 +349,32 @@ 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)
{
static const char *DAHDI_STRING = "dahdi!";
char *udevname;
udevname = kzalloc(strlen(dev->name) + sizeof(DAHDI_STRING) + 1,
GFP_KERNEL);
if (!udevname)
return -ENOMEM;
strcpy(udevname, DAHDI_STRING);
strcat(udevname, dev->name);
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor), NULL, udevname);
kfree(udevname);
return 0;
}
EXPORT_SYMBOL(dahdi_register_chardev);
int dahdi_unregister_chardev(struct dahdi_chardev *dev)
{
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, dev->minor));
return 0;
}
EXPORT_SYMBOL(dahdi_unregister_chardev);
void span_sysfs_remove(struct dahdi_span *span)
{
struct device *span_device;
@@ -330,8 +386,15 @@ void span_sysfs_remove(struct dahdi_span *span)
if (!span_device)
return;
for (x = 0; x < span->channels; x++)
chan_sysfs_remove(span->chans[x]);
for (x = 0; x < span->channels; x++) {
struct dahdi_chan *chan = span->chans[x];
if (!test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
continue;
CLASS_DEV_DESTROY(dahdi_class,
MKDEV(DAHDI_MAJOR, chan->channo));
clear_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
}
if (!dev_get_drvdata(span_device))
return;
@@ -340,7 +403,6 @@ void span_sysfs_remove(struct dahdi_span *span)
get_device(span_device);
span_uevent_send(span, KOBJ_OFFLINE);
sysfs_remove_link(&span_device->kobj, "ddev");
device_unregister(span->span_device);
dev_set_drvdata(span_device, NULL);
span_device->parent = NULL;
@@ -381,20 +443,30 @@ int span_sysfs_create(struct dahdi_span *span)
span->span_device = NULL;
goto cleanup;
}
res = sysfs_create_link(&span_device->kobj, &span_device->parent->kobj,
"ddev");
if (res) {
span_err(span, "%s: sysfs_create_link failed: %d\n", __func__,
res);
kfree(span->span_device);
span->span_device = NULL;
goto cleanup;
}
for (x = 0; x < span->channels; x++) {
res = chan_sysfs_create(span->chans[x]);
if (res)
struct dahdi_chan *chan = span->chans[x];
char chan_name[32];
void *dummy;
if (chan->channo >= 250)
continue;
if (test_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags))
continue;
snprintf(chan_name, sizeof(chan_name), "dahdi!%d",
chan->channo);
dummy = (void *)CLASS_DEV_CREATE(dahdi_class,
MKDEV(DAHDI_MAJOR, chan->channo),
NULL, chan_name);
if (IS_ERR(dummy)) {
res = PTR_ERR(dummy);
chan_err(chan, "Failed creating sysfs device: %d\n",
res);
goto cleanup;
}
set_bit(DAHDI_FLAGBIT_DEVFILE, &chan->flags);
}
return 0;
@@ -403,103 +475,58 @@ cleanup:
return res;
}
#define MAKE_DAHDI_DEV(num, name) \
CLASS_DEV_CREATE(dahdi_class, MKDEV(DAHDI_MAJOR, num), NULL, name)
#define DEL_DAHDI_DEV(num) \
CLASS_DEV_DESTROY(dahdi_class, MKDEV(DAHDI_MAJOR, num))
/* Only used to flag that the device exists: */
static struct {
unsigned int clean_dahdi_driver:1;
unsigned int clean_span_bus_type:1;
unsigned int clean_device_bus:1;
unsigned int clean_chardev:1;
} should_cleanup;
unsigned int ctl:1;
unsigned int timer:1;
unsigned int channel:1;
unsigned int pseudo:1;
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);
}
#define DEVICE_VAR_BLOCK \
do { \
DAHDI_ADD_UEVENT_VAR("DAHDI_TOOLS_ROOTDIR=%s", tools_rootdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_INIT_DIR=%s/%s", tools_rootdir, \
initdir); \
DAHDI_ADD_UEVENT_VAR("DAHDI_DEVICE_HWID=%s", \
ddev->hardware_id); \
DAHDI_ADD_UEVENT_VAR("DAHDI_DEVICE_LOCATION=%s", \
ddev->location); \
} while (0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(envp, num_envp, &i, \
buffer, buffer_size, &len, \
fmt, val); \
if (err) \
return err; \
} while (0)
static int device_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
{
struct dahdi_device *ddev;
int i = 0;
int len = 0;
if (!dev)
return -ENODEV;
ddev = to_ddev(dev);
if (!ddev)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s\n", dev_name(dev));
DEVICE_VAR_BLOCK;
envp[i] = NULL;
return 0;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
static ssize_t dahdi_device_manufacturer_show(struct device *dev, char *buf)
#else
#define DAHDI_ADD_UEVENT_VAR(fmt, val...) \
do { \
int err = add_uevent_var(kenv, fmt, val); \
if (err) \
return err; \
} while (0)
static int device_uevent(struct device *dev, struct kobj_uevent_env *kenv)
{
struct dahdi_device *ddev;
if (!dev)
return -ENODEV;
ddev = to_ddev(dev);
if (!ddev)
return -ENODEV;
dahdi_dbg(GENERAL, "SYFS dev_name=%s\n", dev_name(dev));
DEVICE_VAR_BLOCK;
return 0;
}
#endif
static ssize_t
dahdi_device_manufacturer_show(struct device *dev,
struct device_attribute *attr, char *buf)
#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;
@@ -511,9 +538,13 @@ dahdi_device_span_count_show(struct device *dev,
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);
@@ -521,28 +552,28 @@ dahdi_device_hardware_id_show(struct device *dev,
(ddev->hardware_id) ? ddev->hardware_id : "");
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
static ssize_t
dahdi_device_location_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
return sprintf(buf, "%s\n",
(ddev->location) ? ddev->location : "");
}
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;
@@ -554,7 +585,7 @@ dahdi_device_assign_span(struct device *dev, struct device_attribute *attr,
ret = sscanf(buf, "%u:%u:%u", &local_span_number, &desired_spanno,
&desired_basechanno);
if (ret != 3) {
dev_notice(dev, "bad input (should be <num>:<num>:<num>)\n");
dev_notice(dev, "badly formatted input (should be <num>:<num>:<num>)\n");
return -EINVAL;
}
@@ -570,14 +601,18 @@ dahdi_device_assign_span(struct device *dev, struct device_attribute *attr,
return (ret) ? ret : count;
}
}
dev_notice(dev, "no match for local span number %d\n",
local_span_number);
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;
@@ -603,9 +638,13 @@ dahdi_device_unassign_span(struct device *dev, struct device_attribute *attr,
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;
@@ -614,8 +653,7 @@ dahdi_spantype_show(struct device *dev,
/* TODO: Make sure this doesn't overflow the page. */
list_for_each_entry(span, &ddev->spans, device_node) {
count = sprintf(buf, "%d:%s\n",
local_spanno(span), dahdi_spantype2str(span->spantype));
count = sprintf(buf, "%d:%s\n", local_spanno(span), span->spantype);
buf += count;
total += count;
}
@@ -623,41 +661,28 @@ dahdi_spantype_show(struct device *dev,
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 = NULL;
struct dahdi_span *cur;
struct dahdi_span *span;
unsigned int local_span_number;
char spantype_name[80];
enum spantypes spantype;
char desired_spantype[80];
ret = sscanf(buf, "%u:%70s", &local_span_number, spantype_name);
if (ret != 2) {
dev_err(&ddev->dev, "Wrong input format: '%s'\n", buf);
ret = sscanf(buf, "%u:%70s", &local_span_number, desired_spantype);
if (ret != 2)
return -EINVAL;
}
spantype = dahdi_str2spantype(spantype_name);
if (spantype == SPANTYPE_INVALID) {
dev_err(&ddev->dev, "Invalid spantype: '%s'\n", buf);
return -EINVAL;
}
list_for_each_entry(cur, &ddev->spans, device_node) {
if (local_spanno(cur) == local_span_number) {
span = cur;
list_for_each_entry(span, &ddev->spans, device_node) {
if (local_spanno(span) == local_span_number)
break;
}
}
if (!span || (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 (test_bit(DAHDI_FLAGBIT_REGISTERED, &span->flags)) {
@@ -666,6 +691,11 @@ dahdi_spantype_store(struct device *dev, struct device_attribute *attr,
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 "
@@ -673,68 +703,71 @@ dahdi_spantype_store(struct device *dev, struct device_attribute *attr,
return -EINVAL;
}
ret = span->ops->set_spantype(span, spantype);
ret = span->ops->set_spantype(span, &desired_spantype[0]);
return (ret < 0) ? ret : count;
}
static ssize_t
dahdi_registration_time_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct dahdi_device *ddev = to_ddev(dev);
int count = 0;
count += sprintf(buf, "%010ld.%09ld\n",
ddev->registration_time.tv_sec,
ddev->registration_time.tv_nsec);
return count;
}
static struct device_attribute dahdi_device_attrs[] = {
__ATTR(manufacturer, S_IRUGO, dahdi_device_manufacturer_show, NULL),
__ATTR(type, S_IRUGO, dahdi_device_type_show, NULL),
__ATTR(span_count, S_IRUGO, dahdi_device_span_count_show, NULL),
__ATTR(hardware_id, S_IRUGO, dahdi_device_hardware_id_show, NULL),
__ATTR(location, S_IRUGO, dahdi_device_location_show, NULL),
__ATTR(auto_assign, S_IWUSR, NULL, dahdi_device_auto_assign),
__ATTR(assign_span, S_IWUSR, NULL, dahdi_device_assign_span),
__ATTR(unassign_span, S_IWUSR, NULL, dahdi_device_unassign_span),
__ATTR(spantype, S_IWUSR | S_IRUGO, dahdi_spantype_show,
dahdi_spantype_store),
__ATTR(registration_time, S_IRUGO, dahdi_registration_time_show, NULL),
__ATTR_NULL,
};
static struct bus_type dahdi_device_bus = {
.name = "dahdi_devices",
.uevent = device_uevent,
.dev_attrs = dahdi_device_attrs,
};
static void dahdi_sysfs_cleanup(void)
void dahdi_sysfs_exit(void)
{
dahdi_dbg(DEVICES, "SYSFS\n");
if (should_cleanup.clean_dahdi_driver) {
if (dummy_dev.pseudo) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/pseudo:\n");
DEL_DAHDI_DEV(DAHDI_PSEUDO);
dummy_dev.pseudo = 0;
}
if (dummy_dev.channel) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/channel:\n");
DEL_DAHDI_DEV(DAHDI_CHANNEL);
dummy_dev.channel = 0;
}
if (dummy_dev.timer) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/timer:\n");
DEL_DAHDI_DEV(DAHDI_TIMER);
dummy_dev.timer = 0;
}
if (dummy_dev.ctl) {
dahdi_dbg(DEVICES, "Removing /dev/dahdi/ctl:\n");
DEL_DAHDI_DEV(DAHDI_CTL);
dummy_dev.ctl = 0;
}
if (dahdi_class) {
dahdi_dbg(DEVICES, "Destroying DAHDI class:\n");
class_destroy(dahdi_class);
dahdi_class = NULL;
}
if (dummy_dev.sysfs_driver_registered) {
dahdi_dbg(DEVICES, "Unregister driver\n");
driver_unregister(&dahdi_driver);
should_cleanup.clean_dahdi_driver = 0;
dummy_dev.sysfs_driver_registered = 0;
}
if (should_cleanup.clean_span_bus_type) {
if (dummy_dev.sysfs_spans_bus_type) {
dahdi_dbg(DEVICES, "Unregister span bus type\n");
bus_unregister(&spans_bus_type);
should_cleanup.clean_span_bus_type = 0;
}
dahdi_sysfs_chan_exit();
if (should_cleanup.clean_chardev) {
dahdi_dbg(DEVICES, "Unregister character device\n");
unregister_chrdev(DAHDI_MAJOR, "dahdi");
should_cleanup.clean_chardev = 0;
dummy_dev.sysfs_spans_bus_type = 0;
}
unregister_chrdev(DAHDI_MAJOR, "dahdi");
if (should_cleanup.clean_device_bus) {
dahdi_dbg(DEVICES, "Unregister DAHDI device bus\n");
if (dummy_dev.dahdi_device_bus_registered) {
bus_unregister(&dahdi_device_bus);
should_cleanup.clean_device_bus = 0;
dummy_dev.dahdi_device_bus_registered = 0;
}
}
@@ -786,67 +819,79 @@ void dahdi_sysfs_unregister_device(struct dahdi_device *ddev)
int __init dahdi_sysfs_init(const struct file_operations *dahdi_fops)
{
int res = 0;
dahdi_dbg(DEVICES, "Registering DAHDI device bus\n");
/* Handle dahdi-tools paths (for udev environment) */
if (tools_rootdir && initdir) {
dahdi_err("Cannot use tools-rootdir and initdir parameters simultaneously\n");
return -EINVAL;
}
if (initdir)
pr_notice("dahdi: initdir is depracated -- prefer using \"tools_rootdir\" parameter\n");
else
initdir = "/usr/share/dahdi";
if (!tools_rootdir)
tools_rootdir = "";
void *dev;
res = bus_register(&dahdi_device_bus);
if (res)
return res;
should_cleanup.clean_device_bus = 1;
dahdi_dbg(DEVICES,
"Registering character device (major=%d)\n", DAHDI_MAJOR);
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);
module_printk(KERN_ERR, "Unable to register DAHDI character device handler on %d\n", DAHDI_MAJOR);
return res;
}
should_cleanup.clean_chardev = 1;
module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n",
DAHDI_MAJOR);
module_printk(KERN_INFO, "Version: %s\n", dahdi_version);
res = dahdi_sysfs_chan_init(dahdi_fops);
if (res)
dahdi_class = class_create(THIS_MODULE, "dahdi");
if (!dahdi_class) {
res = -EEXIST;
goto cleanup;
}
dahdi_dbg(DEVICES, "Creating /dev/dahdi/timer:\n");
dev = MAKE_DAHDI_DEV(DAHDI_TIMER, "dahdi!timer");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.timer = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/channel:\n");
dev = MAKE_DAHDI_DEV(DAHDI_CHANNEL, "dahdi!channel");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.channel = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/pseudo:\n");
dev = MAKE_DAHDI_DEV(DAHDI_PSEUDO, "dahdi!pseudo");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.pseudo = 1;
dahdi_dbg(DEVICES, "Creating /dev/dahdi/ctl:\n");
dev = MAKE_DAHDI_DEV(DAHDI_CTL, "dahdi!ctl");
if (IS_ERR(dev)) {
res = PTR_ERR(dev);
goto cleanup;
}
dummy_dev.ctl = 1;
res = bus_register(&spans_bus_type);
if (res) {
if (res != 0) {
dahdi_err("%s: bus_register(%s) failed. Error number %d",
__func__, spans_bus_type.name, res);
goto cleanup;
}
should_cleanup.clean_span_bus_type = 1;
dummy_dev.sysfs_spans_bus_type = 1;
res = driver_register(&dahdi_driver);
if (res) {
if (res < 0) {
dahdi_err("%s: driver_register(%s) failed. Error number %d",
__func__, dahdi_driver.name, res);
goto cleanup;
}
should_cleanup.clean_dahdi_driver = 1;
dummy_dev.sysfs_driver_registered = 1;
module_printk(KERN_INFO, "Telephony Interface Registered on major %d\n",
DAHDI_MAJOR);
return 0;
cleanup:
dahdi_sysfs_cleanup();
dahdi_sysfs_exit();
return res;
}
void dahdi_sysfs_exit(void)
{
dahdi_sysfs_cleanup();
}

View File

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

View File

@@ -6,7 +6,6 @@
*
* Written by Tzafrir Cohen <tzafrir.cohen@xorcom.com>
* Copyright (C) 2011, Xorcom
* Copyright (C) 2011, Digium, Inc
*
* All rights reserved.
*

View File

@@ -10,7 +10,7 @@
* Converted to use HighResTimers on i386 by Jeffery Palmer <jeff@triggerinc.com>
*
* Copyright (C) 2002, Hermes Softlab
* Copyright (C) 2004-2012, Digium, Inc.
* Copyright (C) 2004-2009, Digium, Inc.
*
* All rights reserved.
*

View File

@@ -3,7 +3,7 @@
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2012, Digium, Inc.
* Copyright (C) 2001-2010, Digium, Inc.
*
* All rights reserved.
*
@@ -88,8 +88,6 @@ static int txerrors;
static struct tasklet_struct dahdi_dynamic_tlet;
static void dahdi_dynamic_tasklet(unsigned long data);
#else
static struct tasklet_struct dahdi_dynamic_flush_tlet;
#endif
static DEFINE_MUTEX(dspan_mutex);
@@ -210,25 +208,12 @@ static void __dahdi_dynamic_run(void)
dahdi_dynamic_sendmessage(d);
}
#ifdef ENABLE_TASKLETS
/* If tasklets are not enabled, the above section will be called in
* interrupt context and the flushing of each driver will be called in a
* separate tasklet that only handles that. This is necessary since some
* of the dynamic spans need to call functions that require interrupts
* to be enabled but dahdi_transmit / ...sendmessage needs to be called
* each time the masterspan is processed which happens with interrupts
* disabled.
*
*/
tasklet_hi_schedule(&dahdi_dynamic_flush_tlet);
#else
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
#endif
rcu_read_unlock();
}
@@ -411,7 +396,12 @@ static void dahdi_dynamic_release(struct kref *kref)
static inline int dynamic_put(struct dahdi_dynamic *d)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 12)
kref_put(&d->kref, dahdi_dynamic_release);
return 1;
#else
return kref_put(&d->kref, dahdi_dynamic_release);
#endif
}
static inline void dynamic_get(struct dahdi_dynamic *d)
@@ -630,10 +620,6 @@ static int _create_dynamic(struct dahdi_dynamic_span *dds)
d->span.deflaw = DAHDI_LAW_MULAW;
d->span.flags |= DAHDI_FLAG_RBS;
d->span.chans = d->chans;
d->span.spantype = SPANTYPE_DIGITAL_DYNAMIC;
d->span.linecompat = DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF |
DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_CCS |
DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CRC4 | DAHDI_CONFIG_NOTOPEN;
d->span.ops = &dynamic_ops;
for (x = 0; x < d->span.channels; x++) {
sprintf(d->chans[x]->name, "DYN/%s/%s/%d",
@@ -727,20 +713,6 @@ static void dahdi_dynamic_tasklet(unsigned long data)
}
taskletpending = 0;
}
#else
static void dahdi_dynamic_flush_tasklet(unsigned long data)
{
struct dahdi_dynamic_driver *drv;
rcu_read_lock();
list_for_each_entry_rcu(drv, &driver_list, list) {
/* Flush any traffic still pending in the driver */
if (drv->flush) {
drv->flush();
}
}
rcu_read_unlock();
}
#endif
static int dahdi_dynamic_ioctl(unsigned int cmd, unsigned long data)
@@ -873,8 +845,6 @@ static int dahdi_dynamic_init(void)
mod_timer(&alarmcheck, jiffies + 1 * HZ);
#ifdef ENABLE_TASKLETS
tasklet_init(&dahdi_dynamic_tlet, dahdi_dynamic_tasklet, 0);
#else
tasklet_init(&dahdi_dynamic_flush_tlet, dahdi_dynamic_flush_tasklet, 0);
#endif
dahdi_set_dynamic_ops(&dahdi_dynamic_ops);
@@ -891,9 +861,6 @@ static void dahdi_dynamic_cleanup(void)
tasklet_disable(&dahdi_dynamic_tlet);
tasklet_kill(&dahdi_dynamic_tlet);
}
#else
tasklet_disable(&dahdi_dynamic_flush_tlet);
tasklet_kill(&dahdi_dynamic_flush_tlet);
#endif
del_timer_sync(&alarmcheck);
/* Must call again in case it was running before and rescheduled

View File

@@ -3,7 +3,7 @@
*
* Written by Mark Spencer <markster@digium.com>
*
* Copyright (C) 2001-2012, Digium, Inc.
* Copyright (C) 2001-2008, Digium, Inc.
*
* All rights reserved.
*
@@ -76,7 +76,11 @@ static struct dahdi_span *ztdeth_getspan(unsigned char *addr, unsigned short sub
return span;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
#else
static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
#endif
{
struct dahdi_span *span;
struct ztdeth_header *zh;
@@ -85,7 +89,11 @@ static int ztdeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
#else
zh = (struct ztdeth_header *)skb->nh.raw;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
span = ztdeth_getspan(eth_hdr(skb)->h_source, zh->subaddr);
#else
span = ztdeth_getspan(skb->mac.ethernet->h_source, zh->subaddr);
#endif
if (span) {
skb_pull(skb, sizeof(struct ztdeth_header));
#ifdef NEW_SKB_LINEARIZE
@@ -185,16 +193,44 @@ static void ztdeth_transmit(struct dahdi_dynamic *dyn, u8 *msg, size_t msglen)
spin_unlock_irqrestore(&zlock, flags);
}
/**
* 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 always called in softirq context.
* This function is called in interrupt context while processing the master
* span.
*/
static int ztdeth_flush(void)
{
struct sk_buff *skb;
while ((skb = skb_dequeue(&skbs)))
dev_queue_xmit(skb);
schedule_work(&dahdi_dynamic_eth_flush_work);
return 0;
}
@@ -418,6 +454,11 @@ static int __init ztdeth_init(void)
static void __exit ztdeth_exit(void)
{
#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);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -168,9 +168,8 @@ static void dtc_release(struct dahdi_transcoder_channel *chan)
BUG_ON(!chan);
if (chan->parent && chan->parent->release) {
chan->parent->release(chan);
} else {
dahdi_tc_clear_busy(chan);
}
dahdi_tc_clear_busy(chan);
}
static int dahdi_tc_release(struct inode *inode, struct file *file)

View File

@@ -51,7 +51,6 @@
#include <linux/pkt_sched.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <linux/slab.h>
#include <net/syncppp.h>

View File

@@ -3,7 +3,7 @@
#
# Makefile for firmware downloading/installation
#
# Copyright (C) 2007-2013, Digium, Inc.
# Copyright (C) 2007-2010, Digium, Inc.
#
# Joshua Colp <jcolp@digium.com>
#
@@ -22,7 +22,6 @@
.PHONY: dist-clean clean all uninstall have_download install object-build hotplug-install hotplug-dirs hotplug-uninstall make_firmware_object firmware-loaders
OCT6114_032_VERSION:=1.05.01
OCT6114_064_VERSION:=1.05.01
OCT6114_128_VERSION:=1.05.01
OCT6114_256_VERSION:=1.05.01
@@ -31,19 +30,10 @@ VPMADT032_VERSION:=1.25.0
HX8_VERSION:=2.06
VPMOCT032_VERSION:=1.12.0
WCT820_VERSION:=1.76
TE133_VERSION:=780019
TE134_VERSION:=780017
TE435_VERSION:=e0019
A8A_VERSION:=1d0017
A8B_VERSION:=1d0019
A4A_VERSION:=a0017
A4B_VERSION:=b0019
FIRMWARE_URL:=http://downloads.digium.com/pub/telephony/firmware/releases
ALL_FIRMWARE=FIRMWARE-OCT6114-032 FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-OCT6114-256
ALL_FIRMWARE+=FIRMWARE-TC400M FIRMWARE-HX8 FIRMWARE-VPMOCT032 FIRMWARE-TE820 FIRMWARE-TE133 FIRMWARE-TE134
ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
ALL_FIRMWARE=FIRMWARE-OCT6114-064 FIRMWARE-OCT6114-128 FIRMWARE-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
@@ -52,26 +42,17 @@ ALL_FIRMWARE+=FIRMWARE-A8A FIRMWARE-A8B FIRMWARE-A4A FIRMWARE-A4B FIRMWARE-TE435
# This means this is version MR5.6 of the tc400m firmware
# Build a list of firmware package filenames we need
FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-032=dahdi-fw-oct6114-032-$(OCT6114_032_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz)
FIRMWARE:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128-$(OCT6114_128_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256-$(OCT6114_256_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TC400M=dahdi-fw-tc400m-$(TC400M_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-HX8=dahdi-fw-hx8-$(HX8_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032-$(VPMOCT032_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE820=dahdi-fw-te820-$(WCT820_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE133=dahdi-fw-te133-$(TE133_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE134=dahdi-fw-te134-$(TE134_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-TE435=dahdi-fw-te435-$(TE435_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8A=dahdi-fw-a8b-$(A8B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A8B=dahdi-fw-a8a-$(A8A_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4A=dahdi-fw-a4b-$(A4B_VERSION).tar.gz)
FIRMWARE:=$(FIRMWARE:FIRMWARE-A4B=dahdi-fw-a4a-$(A4A_VERSION).tar.gz)
FWLOADERS:=dahdi-fwload-vpmadt032-$(VPMADT032_VERSION).tar.gz
# Build a list of object files if hotplug will not be used
OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-032=dahdi-fw-oct6114-032.o)
OBJECT_FILES:=$(ALL_FIRMWARE:FIRMWARE-OCT6114-064=dahdi-fw-oct6114-064.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-128=dahdi-fw-oct6114-128.o)
OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-OCT6114-256=dahdi-fw-oct6114-256.o)
@@ -82,8 +63,6 @@ OBJECT_FILES:=$(OBJECT_FILES:FIRMWARE-VPMOCT032=dahdi-fw-vpmoct032.o)
# Force usage of wget, for now
DOWNLOAD=wget
WGET=wget
INSTALL_FIRMWARE=../../../build_tools/install_firmware
RUN_INST=$(INSTALL_FIRMWARE) $(1) $(2) $(DESTDIR)
# If "fetch" is used, --continue is not a valid option.
ifeq ($(WGET),wget)
@@ -109,6 +88,7 @@ dahdi-fw-%.tar.gz:
echo "Attempting to download $@"; \
if test ! -f $@; then $(DOWNLOAD) $(WGET_ARGS) $(FIRMWARE_URL)/$@; fi; \
if test ! -f $@; then exit 1; fi; \
(cat $@ | gzip -d | tar --no-same-owner -xf -) \
fi
firmware-loaders: $(FWLOADERS)
@@ -127,21 +107,83 @@ $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware:
# Install all downloaded firmware images for hotplug usage
hotplug-install: $(DESTDIR)/usr/lib/hotplug/firmware $(DESTDIR)/lib/firmware $(FIRMWARE)
@$(call RUN_INST,dahdi-fw-oct6114-032,$(OCT6114_032_VERSION))
@$(call RUN_INST,dahdi-fw-oct6114-064,$(OCT6114_064_VERSION))
@$(call RUN_INST,dahdi-fw-oct6114-128,$(OCT6114_128_VERSION))
@$(call RUN_INST,dahdi-fw-oct6114-256,$(OCT6114_256_VERSION))
@$(call RUN_INST,dahdi-fw-tc400m,$(TC400M_VERSION))
@$(call RUN_INST,dahdi-fw-hx8,$(HX8_VERSION))
@$(call RUN_INST,dahdi-fw-vpmoct032,$(VPMOCT032_VERSION))
@$(call RUN_INST,dahdi-fw-te820,$(WCT820_VERSION))
@$(call RUN_INST,dahdi-fw-te133,$(TE133_VERSION))
@$(call RUN_INST,dahdi-fw-te134,$(TE134_VERSION))
@$(call RUN_INST,dahdi-fw-te435,$(TE435_VERSION))
@$(call RUN_INST,dahdi-fw-a8a,$(A8A_VERSION))
@$(call RUN_INST,dahdi-fw-a8b,$(A8B_VERSION))
@$(call RUN_INST,dahdi-fw-a4a,$(A4A_VERSION))
@$(call RUN_INST,dahdi-fw-a4b,$(A4B_VERSION))
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-oct6114-064.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION)
@install -m 644 dahdi-fw-oct6114-064.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-064-$(OCT6114_064_VERSION)
else
@echo "Firmware dahdi-fw-oct6114-064.bin is already installed with required version $(OCT6114_064_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-oct6114-128.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION)
@install -m 644 dahdi-fw-oct6114-128.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-oct6114-128-$(OCT6114_128_VERSION)
else
@echo "Firmware dahdi-fw-oct6114-128.bin is already installed with required version $(OCT6114_128_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-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
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION)
@install -m 644 dahdi-fw-tc400m.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-tc400m-$(TC400M_VERSION)
else
@echo "Firmware dahdi-fw-tc400m.bin is already installed with required version $(TC400M_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-$(HX8_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-$(HX8_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-hx8.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-hx8.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-hx8-$(HX8_VERSION)
@install -m 644 dahdi-fw-hx8.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-hx8-$(HX8_VERSION)
else
@echo "Firmware dahdi-fw-hx8.bin is already installed with required version $(HX8_VERSION)"
endif
ifeq ($(shell if ( [ -f $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION) ] ) && ( [ -f $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION) ] ); then echo "no"; else echo "yes"; fi),yes)
@echo "Installing dahdi-fw-vpmoct032.bin to hotplug firmware directories"
@install -m 644 dahdi-fw-vpmoct032.bin $(DESTDIR)/usr/lib/hotplug/firmware
@rm -rf $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-*
@touch $(DESTDIR)/usr/lib/hotplug/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION)
@install -m 644 dahdi-fw-vpmoct032.bin $(DESTDIR)/lib/firmware
@rm -rf $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-*
@touch $(DESTDIR)/lib/firmware/.dahdi-fw-vpmoct032-$(VPMOCT032_VERSION)
else
@echo "Firmware dahdi-fw-vpmoct032.bin is already installed with required version $(VPMOCT032_VERSION)"
endif
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:
@@ -160,11 +202,6 @@ make_firmware_object: make_firmware_object.in ../dahdi-base.o
sed -e s/BFDNAME/$${BFDNAME}/ -e s/BFDARCH/$${BFDARCH}/ $< > $@
@chmod +x $@
# Build object file of an oct6114 032 firmware image for linking
dahdi-fw-oct6114-032.o: dahdi-fw-oct6114-032-$(OCT6114_032_VERSION).tar.gz dahdi-fw-oct6114-032.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-oct6114-032.bin
./make_firmware_object dahdi-fw-oct6114-032.bin $@
# Build object file of an oct6114 064 firmware image for linking
dahdi-fw-oct6114-064.o: dahdi-fw-oct6114-064-$(OCT6114_064_VERSION).tar.gz dahdi-fw-oct6114-064.bin make_firmware_object
@echo Making firmware object file for dahdi-fw-oct6114-064.bin

View File

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

View File

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

View File

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

View File

@@ -129,7 +129,7 @@ $Octasic_Revision: 16 $
/***************************** TYPES ***************************************/
/*Change this type if your platform uses 64bits semaphores/locks */
typedef void* tOCT6100_USER_SERIAL_OBJECT;
typedef UINT32 tOCT6100_USER_SERIAL_OBJECT;
typedef struct _OCT6100_GET_TIME_
{

View File

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

View File

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

View File

@@ -51,8 +51,6 @@ With driver: 303826 (1.5 %)
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/delay.h>
@@ -482,6 +480,8 @@ static void rbi_out(struct pciradio *rad, int n, unsigned char *rbicmd)
{
unsigned long flags;
int x;
DECLARE_WAIT_QUEUE_HEAD(mywait);
for(;;)
{
@@ -489,8 +489,7 @@ int x;
x = rad->remote_locked || (__pciradio_getcreg(rad,0xc) & 2);
if (!x) rad->remote_locked = 1;
spin_unlock_irqrestore(&rad->lock,flags);
if (x)
msleep_interruptible(20);
if (x) interruptible_sleep_on_timeout(&mywait,2);
else break;
}
spin_lock_irqsave(&rad->lock,flags);
@@ -527,6 +526,7 @@ static void mx828_command(struct pciradio *rad,int channel, unsigned char comman
static void mx828_command_wait(struct pciradio *rad,int channel, unsigned char command, unsigned char *byte1, unsigned char *byte2)
{
DECLARE_WAIT_QUEUE_HEAD(mywait);
unsigned long flags;
@@ -534,7 +534,7 @@ unsigned long flags;
while(rad->encdec.state)
{
spin_unlock_irqrestore(&rad->lock,flags);
msleep_interruptible(20);
interruptible_sleep_on_timeout(&mywait,2);
spin_lock_irqsave(&rad->lock,flags);
}
rad->encdec.lastcmd = jiffies + 1000;
@@ -966,6 +966,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
} stack;
struct pciradio *rad = chan->pvt;
DECLARE_WAIT_QUEUE_HEAD(mywait);
switch (cmd) {
case DAHDI_RADIO_GETPARAM:
@@ -1253,7 +1254,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
__pciradio_setcreg(rad,8,byte2);
spin_unlock_irqrestore(&rad->lock,flags);
if (i || (jiffies < rad->lastremcmd + 10))
msleep_interruptible(100);
interruptible_sleep_on_timeout(&mywait,10);
rad->lastremcmd = jiffies;
rbi_out(rad,chan->chanpos - 1,(unsigned char *)&stack.p.data);
spin_lock_irqsave(&rad->lock,flags);
@@ -1268,8 +1269,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
x = rad->remote_locked || (__pciradio_getcreg(rad,0xc) & 2);
if (!x) rad->remote_locked = 1;
spin_unlock_irqrestore(&rad->lock,flags);
if (x)
msleep_interruptible(20);
if (x) interruptible_sleep_on_timeout(&mywait,2);
else break;
}
spin_lock_irqsave(&rad->lock,flags);
@@ -1286,14 +1286,14 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
__pciradio_setcreg(rad,8,byte2);
spin_unlock_irqrestore(&rad->lock,flags);
if (byte1 != byte2)
msleep_interruptible(30);
interruptible_sleep_on_timeout(&mywait,3);
while (jiffies < rad->lastremcmd + 10)
msleep_interruptible(100);
interruptible_sleep_on_timeout(&mywait,10);
rad->lastremcmd = jiffies;
for(;;)
{
if (!(__pciradio_getcreg(rad,0xc) & 2)) break;
msleep_interruptible(20);
interruptible_sleep_on_timeout(&mywait,2);
}
spin_lock_irqsave(&rad->lock,flags);
/* enable and address async serializer */
@@ -1315,7 +1315,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
(!strchr((char *)rad->rxbuf,'\r'))))
{
spin_unlock_irqrestore(&rad->lock,flags);
msleep_interruptible(20);
interruptible_sleep_on_timeout(&mywait,2);
spin_lock_irqsave(&rad->lock,flags);
continue;
}
@@ -1335,7 +1335,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
while(rad->txlen && (rad->txindex < rad->txlen))
{
spin_unlock_irqrestore(&rad->lock,flags);
msleep_interruptible(20);
interruptible_sleep_on_timeout(&mywait,2);
spin_lock_irqsave(&rad->lock,flags);
}
/* disable and un-address async serializer */
@@ -1344,7 +1344,7 @@ static int pciradio_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned lo
rad->remote_locked = 0;
spin_unlock_irqrestore(&rad->lock,flags);
if (rad->remmode[chan->chanpos - 1] == DAHDI_RADPAR_REM_SERIAL_ASCII)
msleep_interruptible(1000);
interruptible_sleep_on_timeout(&mywait,100);
if (copy_to_user((__user void *) data, &stack.p, sizeof(stack.p))) return -EFAULT;
return 0;
default:

View File

@@ -31,7 +31,6 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
#define NEED_PCI_IDS
@@ -254,6 +253,16 @@ static int tor2_chanconfig(struct file *file,
return 0;
}
static int tor2_open(struct dahdi_chan *chan)
{
return 0;
}
static int tor2_close(struct dahdi_chan *chan)
{
return 0;
}
static const struct dahdi_span_ops tor2_span_ops = {
.owner = THIS_MODULE,
.spanconfig = tor2_spanconfig,
@@ -262,6 +271,8 @@ static const struct dahdi_span_ops tor2_span_ops = {
.shutdown = tor2_shutdown,
.rbsbits = tor2_rbsbits,
.maint = tor2_maint,
.open = tor2_open,
.close = tor2_close,
.ioctl = tor2_ioctl,
};
@@ -279,12 +290,12 @@ static void init_spans(struct tor2 *tor)
s->channels = 24;
s->deflaw = DAHDI_LAW_MULAW;
s->linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
s->spantype = SPANTYPE_DIGITAL_T1;
s->spantype = "T1";
} else {
s->channels = 31;
s->deflaw = DAHDI_LAW_ALAW;
s->linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
s->spantype = SPANTYPE_DIGITAL_E1;
s->spantype = "E1";
}
s->chans = tor->chans[x];
s->flags = DAHDI_FLAG_RBS;

View File

@@ -38,7 +38,6 @@
#else
#include <asm/semaphore.h>
#endif
#include <linux/slab.h>
#include <dahdi/kernel.h>
#include <dahdi/user.h>

View File

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

View File

@@ -27,7 +27,6 @@
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>

View File

@@ -26,7 +26,6 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include "voicebus/vpmoct.h"
#include "linux/firmware.h"

View File

@@ -1,7 +1,7 @@
/*
* DAHDI Telephony Interface to VPMADT032 Firmware Loader
*
* Copyright (C) 2008-2012 Digium, Inc. All rights reserved.
* Copyright (C) 2008-2011 Digium, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,7 +23,6 @@
#include <linux/ctype.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
@@ -39,9 +38,18 @@ logger(const char *format, ...)
int res;
va_list args;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
va_start(args, format);
res = vprintk(format, args);
va_end(args);
#else
char buf[256];
va_start(args, format);
res = vsnprintf(buf, sizeof(buf), format, args);
va_end(args);
printk(KERN_INFO "%s" buf);
#endif
return res;
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -2,7 +2,7 @@
* WCB410P Quad-BRI PCI Driver
* Written by Andrew Kohlsmith <akohlsmith@mixdown.ca>
*
* Copyright (C) 2009-2012 Digium, Inc.
* Copyright (C) 2009-2011 Digium, Inc.
* All rights reserved.
*
*/
@@ -40,7 +40,6 @@
#include <linux/timer.h> /* timer_struct */
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
@@ -91,7 +90,6 @@ static int milliwatt = 0;
static int pedanticpci = 0;
static int teignorered = 0;
static int alarmdebounce = 500;
static int persistentlayer1 = 1;
static int vpmsupport = 1;
static int timer_1_ms = 2000;
static int timer_3_ms = 30000;
@@ -141,7 +139,7 @@ static struct devtype hfc8s_BN = {"BeroNet BN8S0", .ports = 8, .card_type = BN8S
static struct devtype hfc4s_SW = {"Swyx 4xS0 SX2 QuadBri", .ports = 4, .card_type = BSWYX_SX2 };
static struct devtype hfc4s_EV = {"CCD HFC-4S Eval. Board", .ports = 4,
.card_type = QUADBRI_EVAL };
#define CARD_HAS_EC(card) ((card)->card_type == B410P)
static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec);
@@ -1199,6 +1197,7 @@ static int b4xxp_find_sync(struct b4xxp *b4)
return src;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
static ssize_t b4_timing_master_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -1226,6 +1225,13 @@ static void remove_sysfs_files(struct b4xxp *b4)
&dev_attr_timing_master);
}
#else
static inline void create_sysfs_files(struct b4xxp *b4) { return; }
static inline void remove_sysfs_files(struct b4xxp *b4) { return; }
#endif /* LINUX_KERNEL > 2.6.18 */
/*
* allocates memory and pretty-prints a given S/T state engine state to it.
* calling routine is responsible for freeing the pointer returned!
@@ -1297,9 +1303,6 @@ static void hfc_force_st_state(struct b4xxp *b4, int port, int state, int resume
hfc_handle_state(&b4->spans[port]);
}
static void hfc_stop_st(struct b4xxp_span *s);
static void hfc_start_st(struct b4xxp_span *s);
/* figures out what to do when an S/T port's timer expires. */
static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
{
@@ -1313,15 +1316,10 @@ static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
s->hfc_timer_on[t_no]);
}
/*
* There are four timers associated with every HFC S/T port:
* T1 is used by the NT state machine, and is the maximum time the NT side
* should wait for G3 (active) state.
* T2 is not actually used in the driver, it is handled by the HFC-4S
* internally.
* T3 is used by the TE state machine; it is the maximum time the TE side should
* wait for the INFO4 (activated) signal.
* T4 is a special timer used for debug purposes for monitoring of L1 state
* during activation attempt.
* there are three timers associated with every HFC S/T port.
* T1 is used by the NT state machine, and is the maximum time the NT side should wait for G3 (active) state.
* T2 is not actually used in the driver, it is handled by the HFC-4S internally.
* T3 is used by the TE state machine; it is the maximum time the TE side should wait for the INFO4 (activated) signal.
*/
/* First, disable the expired timer; hfc_force_st_state() may activate it again. */
@@ -1335,14 +1333,7 @@ static void hfc_timer_expire(struct b4xxp_span *s, int t_no)
hfc_force_st_state(b4, s->port, 1, 1);
break;
case HFC_T3: /* switch to F3 (deactivated), resume auto mode */
hfc_stop_st(s);
if (persistentlayer1)
hfc_start_st(s);
break;
case HFC_T4:
hfc_handle_state(s);
s->hfc_timers[HFC_T4] = b4->ticks + 1000;
s->hfc_timer_on[HFC_T4] = 1;
hfc_force_st_state(b4, s->port, 3, 1);
break;
default:
if (printk_ratelimit()) {
@@ -1365,9 +1356,9 @@ static void hfc_update_st_timers(struct b4xxp *b4)
for (i=0; i < b4->numspans; i++) {
s = &b4->spans[i];
for (j = HFC_T1; j < ARRAY_SIZE(s->hfc_timers); j++) {
/* we don't really do timer2, it is expired by the
* state change handler */
for (j=HFC_T1; j <= HFC_T3; j++) {
/* we don't really do timer2, it is expired by the state change handler */
if (j == HFC_T2)
continue;
@@ -1451,7 +1442,6 @@ static void hfc_handle_state(struct b4xxp_span *s)
break;
case 0x7: /* TE state F7: Activated */
s->hfc_timer_on[HFC_T3] = 0;
s->hfc_timer_on[HFC_T4] = 0;
s->newalarm = 0;
break;
}
@@ -1473,17 +1463,14 @@ static void hfc_handle_state(struct b4xxp_span *s)
/* If we're in F3 and receiving INFO0, start T3 and jump to F4 */
if (!nt && (sta == 3) && (state & V_INFO0)) {
if (persistentlayer1) {
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timer_on[HFC_T3] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"port %d: receiving INFO0 in state 3, "
"setting T3 and jumping to F4\n",
s->port + 1);
}
hfc_start_st(s);
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timer_on[HFC_T3] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"port %d: receiving INFO0 in state 3, "
"setting T3 and jumping to F4\n", s->port + 1);
}
hfc_force_st_state(b4, s->port, 4, 1);
}
/* read in R_BERT_STA to determine where our current sync source is */
@@ -1498,24 +1485,6 @@ static void hfc_handle_state(struct b4xxp_span *s)
}
}
static void hfc_stop_all_timers(struct b4xxp_span *s)
{
s->hfc_timer_on[HFC_T4] = 0;
s->hfc_timer_on[HFC_T3] = 0;
s->hfc_timer_on[HFC_T2] = 0;
s->hfc_timer_on[HFC_T1] = 0;
}
static void hfc_stop_st(struct b4xxp_span *s)
{
struct b4xxp *b4 = s->parent;
hfc_stop_all_timers(s);
b4xxp_setreg_ra(b4, R_ST_SEL, s->port, A_ST_WR_STA,
V_ST_ACT_DEACTIVATE);
}
/*
* resets an S/T interface to a given NT/TE mode
*/
@@ -1526,16 +1495,10 @@ static void hfc_reset_st(struct b4xxp_span *s)
b4 = s->parent;
hfc_stop_st(s);
/* force state G0/F0 (reset), then force state 1/2 (deactivated/sensing) */
b4xxp_setreg_ra(b4, R_ST_SEL, s->port, A_ST_WR_STA, V_ST_LD_STA);
flush_pci(); /* make sure write hit hardware */
s->span.alarms = DAHDI_ALARM_RED;
s->newalarm = DAHDI_ALARM_RED;
dahdi_alarm_notify(&s->span);
udelay(10);
/* set up the clock control register. Must be done before we activate the interface. */
@@ -1566,13 +1529,9 @@ static void hfc_start_st(struct b4xxp_span *s)
/* start T1 if in NT mode, T3 if in TE mode */
if (s->te_mode) {
s->hfc_timers[HFC_T3] = b4->ticks + timer_3_ms;
s->hfc_timers[HFC_T3] = b4->ticks + 500; /* 500ms wait first time, timer_t3_ms afterward. */
s->hfc_timer_on[HFC_T3] = 1;
s->hfc_timer_on[HFC_T1] = 0;
s->hfc_timers[HFC_T4] = b4->ticks + 1000;
s->hfc_timer_on[HFC_T4] = 1;
if (DBG_ST) {
dev_info(&b4->pdev->dev,
"setting port %d t3 timer to %lu\n",
@@ -1590,6 +1549,17 @@ static void hfc_start_st(struct b4xxp_span *s)
}
}
#if 0 /* TODO: This function is not called anywhere */
static void hfc_stop_st(struct b4xxp_span *s)
{
b4xxp_setreg_ra(s->parent, R_ST_SEL, s->port, A_ST_WR_STA, V_ST_ACT_DEACTIVATE);
s->hfc_timer_on[HFC_T1] = 0;
s->hfc_timer_on[HFC_T2] = 0;
s->hfc_timer_on[HFC_T3] = 0;
}
#endif
/*
* read in the HFC GPIO to determine each port's mode (TE or NT).
* Then, reset and start the port.
@@ -1622,6 +1592,8 @@ static void hfc_init_all_st(struct b4xxp *b4)
dev_info(&b4->pdev->dev,
"Port %d: %s mode\n", i + 1, (nt ? "NT" : "TE"));
hfc_reset_st(s);
hfc_start_st(s);
}
}
@@ -1878,10 +1850,10 @@ static int hdlc_tx_frame(struct b4xxp_span *bspan)
char debugbuf[256];
unsigned long irq_flags;
/* if we're ignoring TE red alarms and we are in alarm, restart the
* S/T state machine */
if (bspan->te_mode && bspan->newalarm != 0)
hfc_start_st(bspan);
/* if we're ignoring TE red alarms and we are in alarm, restart the S/T state machine */
if (bspan->te_mode && teignorered && bspan->newalarm == DAHDI_ALARM_RED) {
hfc_force_st_state(b4, bspan->port, 3, 1);
}
fifo = bspan->fifos[2];
res = dahdi_hdlc_getbuf(bspan->sigchan, buf, &size);
@@ -2369,10 +2341,6 @@ static int b4xxp_spanconfig(struct file *file, struct dahdi_span *span,
if (lc->sync)
b4->spans[lc->sync - 1].sync = (span->offset + 1);
hfc_reset_st(bspan);
if (persistentlayer1)
hfc_start_st(bspan);
b4xxp_reset_span(bspan);
/* call startup() manually here, because DAHDI won't call the startup function unless it receives an IOCTL to do so, and dahdi_cfg doesn't. */
@@ -2430,7 +2398,7 @@ b4xxp_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
return 0;
}
static int _b4xxp_open(struct dahdi_chan *chan)
static int b4xxp_open(struct dahdi_chan *chan)
{
struct b4xxp *b4 = chan->pvt;
struct b4xxp_span *bspan = &b4->spans[chan->span->offset];
@@ -2444,15 +2412,6 @@ static int _b4xxp_open(struct dahdi_chan *chan)
return 0;
}
static int b4xxp_open(struct dahdi_chan *chan)
{
unsigned long flags;
int res;
spin_lock_irqsave(&chan->lock, flags);
res = _b4xxp_open(chan);
spin_unlock_irqrestore(&chan->lock, flags);
return res;
}
static int b4xxp_close(struct dahdi_chan *chan)
{
@@ -2516,9 +2475,7 @@ static void init_spans(struct b4xxp *b4)
bspan = &b4->spans[i];
bspan->parent = b4;
bspan->span.spantype = (bspan->te_mode)
? SPANTYPE_DIGITAL_BRI_TE
: SPANTYPE_DIGITAL_BRI_NT;
bspan->span.spantype = (bspan->te_mode) ? "TE" : "NT";
bspan->span.offset = i;
bspan->span.channels = WCB4XXP_CHANNELS_PER_SPAN;
bspan->span.flags = 0;
@@ -3162,7 +3119,6 @@ module_param(vpmsupport, int, S_IRUGO);
module_param(timer_1_ms, int, S_IRUGO | S_IWUSR);
module_param(timer_3_ms, int, S_IRUGO | S_IWUSR);
module_param(companding, charp, S_IRUGO);
module_param(persistentlayer1, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "bitmap: 1=general 2=dtmf 4=regops 8=fops 16=ec 32=st state 64=hdlc 128=alarm");
MODULE_PARM_DESC(spanfilter, "debug filter for spans. bitmap: 1=port 1, 2=port 2, 4=port 3, 8=port 4");

View File

@@ -376,7 +376,6 @@
#define HFC_T1 0
#define HFC_T2 1
#define HFC_T3 2
#define HFC_T4 3
#define MAX_SPANS_PER_CARD 8
@@ -397,8 +396,8 @@ struct b4xxp_span {
unsigned long alarmtimer;
int te_mode; /* 1=TE, 0=NT */
unsigned long hfc_timers[4]; /* T1, T2, T3, Fake T4 */
int hfc_timer_on[4]; /* 1=timer active */
unsigned long hfc_timers[WCB4XXP_CHANNELS_PER_SPAN]; /* T1, T2, T3 */
int hfc_timer_on[WCB4XXP_CHANNELS_PER_SPAN]; /* 1=timer active */
int fifos[WCB4XXP_CHANNELS_PER_SPAN]; /* B1, B2, D <--> host fifo numbers */
/* HDLC controller fields */

View File

@@ -31,7 +31,6 @@
#include <linux/pci.h>
#include <asm/io.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
@@ -570,7 +569,7 @@ static inline struct wcfxo *wcfxo_from_span(struct dahdi_span *span)
return container_of(span, struct wcfxo, span);
}
static int _wcfxo_open(struct dahdi_chan *chan)
static int wcfxo_open(struct dahdi_chan *chan)
{
struct wcfxo *wc = chan->pvt;
if (wc->dead)
@@ -579,16 +578,6 @@ static int _wcfxo_open(struct dahdi_chan *chan)
return 0;
}
static int wcfxo_open(struct dahdi_chan *chan)
{
int res;
unsigned long flags;
spin_lock_irqsave(&chan->lock, flags);
res = _wcfxo_open(chan);
spin_unlock_irqrestore(&chan->lock, flags);
return res;
}
static int wcfxo_watchdog(struct dahdi_span *span, int event)
{
printk(KERN_INFO "FXO: Restarting DMA\n");

View File

@@ -32,7 +32,6 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
@@ -793,12 +792,12 @@ static int t1xxp_software_init(struct t1xxp *wc)
wc->span.channels = 31;
wc->span.deflaw = DAHDI_LAW_ALAW;
wc->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
wc->span.spantype = SPANTYPE_DIGITAL_E1;
wc->span.spantype = "E1";
} else {
wc->span.channels = 24;
wc->span.deflaw = DAHDI_LAW_MULAW;
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
wc->span.spantype = SPANTYPE_DIGITAL_T1;
wc->span.spantype = "T1";
}
for (x=0;x<wc->span.channels;x++) {
sprintf(wc->chans[x]->name, "WCT1/%d/%d", wc->num, x + 1);

View File

@@ -2,7 +2,7 @@ obj-$(DAHDI_BUILD_ALL)$(CONFIG_DAHDI_WCT4XXP) += wct4xxp.o
FIRM_DIR := ../firmware
EXTRA_CFLAGS += -I$(src)/.. -I$(src)/../oct612x/ $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
EXTRA_CFLAGS += -I$(src)/.. $(shell $(src)/../oct612x/octasic-helper cflags $(src)/../oct612x) -Wno-undef
# The OCT612X source files are from a vendor drop and we do not want to edit
# them to make this warning go away. Therefore, turn off the
@@ -14,7 +14,7 @@ ifeq ($(HOTPLUG_FIRMWARE),yes)
EXTRA_CFLAGS+=-DHOTPLUG_FIRMWARE
endif
wct4xxp-objs := base.o vpm450m.o
wct4xxp-objs := base.o vpm450m.o $(shell $(src)/../oct612x/octasic-helper objects ../oct612x)
ifneq ($(HOTPLUG_FIRMWARE),yes)
wct4xxp-objs += $(FIRM_DIR)/dahdi-fw-oct6114-064.o $(FIRM_DIR)/dahdi-fw-oct6114-128.o $(FIRM_DIR)/dahdi-fw-oct6114-256.o

View File

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

View File

@@ -9,7 +9,7 @@
* Russ Meyerriecks <rmeyerriecks@digium.com>
*
* Copyright (C) 2001 Jim Dixon / Zapata Telephony.
* Copyright (C) 2001-2012, Digium, Inc.
* Copyright (C) 2001-2011, Digium, Inc.
*
* All rights reserved.
*
@@ -40,7 +40,6 @@
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/crc32.h>
#include <linux/slab.h>
#include <stdbool.h>
#include <dahdi/kernel.h>
@@ -120,7 +119,11 @@ struct cpu_workqueue_struct {
*/
struct workqueue_struct {
/* TODO: Find out exactly where the API changed */
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
struct cpu_workqueue_struct *cpu_wq;
#else
struct cpu_workqueue_struct cpu_wq[NR_CPUS];
#endif
const char *name;
struct list_head list; /* Empty if single thread */
};
@@ -184,7 +187,7 @@ static inline int t4_queue_work(struct workqueue_struct *wq, struct work_struct
"CONFIG_NOEXTENDED_RESET."
#endif
int debug = 0;
static int debug=0;
static int timingcable = 0;
static int t1e1override = -1; /* deprecated */
static char *default_linemode = "auto";
@@ -300,7 +303,6 @@ struct t4_span {
unsigned long alarmcheck_time;
int spanflags;
int syncpos;
#ifdef SUPPORT_GEN1
int e1check; /* E1 check */
#endif
@@ -347,7 +349,6 @@ struct t4 {
int irq; /* IRQ used by device */
int order; /* Order */
const struct devtype *devtype;
unsigned int reset_required:1; /* If reset needed in serial_setup */
unsigned int falc31:1; /* are we falc v3.1 (atomic not necessary) */
unsigned int t1e1:8; /* T1 / E1 select pins */
int ledreg; /* LED Register */
@@ -371,14 +372,9 @@ struct t4 {
dma_addr_t writedma;
void __iomem *membase; /* Base address of card */
#define T4_CHECK_VPM 0
#define T4_LOADING_FW 1
#define T4_STOP_DMA 2
#define T4_CHECK_TIMING 3
#define T4_CHANGE_LATENCY 4
#define T4_IGNORE_LATENCY 5
/* Flags for our bottom half */
unsigned long checkflag;
struct work_struct bh_work;
struct tasklet_struct t4_tlet;
/* Latency related additions */
unsigned char rxident;
unsigned char lastindex;
@@ -398,7 +394,7 @@ static inline bool is_pcie(const struct t4 *wc)
static inline bool has_e1_span(const struct t4 *wc)
{
return (wc->t1e1 > 0);
return (wc->t1e1) != 0;
}
static inline bool is_octal(const struct t4 *wc)
@@ -444,7 +440,6 @@ static const struct dahdi_echocan_ops vpm_ec_ops = {
#endif
static void __set_clear(struct t4 *wc, int span);
static int _t4_startup(struct file *file, struct dahdi_span *span);
static int t4_startup(struct file *file, struct dahdi_span *span);
static int t4_shutdown(struct dahdi_span *span);
static int t4_rbsbits(struct dahdi_chan *chan, int bits);
@@ -513,7 +508,7 @@ static void t4_check_sigbits(struct t4 *wc, int span);
#define FMR5_EIBR (1 << 6) /* Internal Bit Robbing Access */
#define DEC_T 0x60 /* Diable Error Counter */
#define IERR_T 0x1B /* Single Bit Defect Insertion Register */
#define IBV (1 << 0) /* Bipolar violation */
#define IBV 0 /* Bipolar violation */
#define IPE (1 << 1) /* PRBS defect */
#define ICASE (1 << 2) /* CAS defect */
#define ICRCE (1 << 3) /* CRC defect */
@@ -554,6 +549,8 @@ static void t4_check_sigbits(struct t4 *wc, int span);
#define MAX_T4_CARDS 64
static void t4_isr_bh(unsigned long data);
static struct t4 *cards[MAX_T4_CARDS];
struct t8_firm_header {
@@ -1125,11 +1122,15 @@ static int t4_echocan_create(struct dahdi_chan *chan,
struct t4 *wc = chan->pvt;
struct t4_span *tspan = container_of(chan->span, struct t4_span, span);
int channel;
const bool alaw = (chan->span->deflaw == 2);
const struct dahdi_echocan_ops *ops;
const struct dahdi_echocan_features *features;
if (!vpmsupport || !wc->vpm)
return -ENODEV;
ops = &vpm_ec_ops;
features = &vpm_ec_features;
if (ecp->param_count > 0) {
dev_warn(&wc->dev->dev, "%s echo canceller does not support "
"parameters; failing request\n",
@@ -1138,24 +1139,24 @@ static int t4_echocan_create(struct dahdi_chan *chan,
}
*ec = tspan->ec[chan->chanpos - 1];
(*ec)->ops = &vpm_ec_ops;
(*ec)->features = vpm_ec_features;
(*ec)->ops = ops;
(*ec)->features = *features;
channel = has_e1_span(wc) ? chan->chanpos : chan->chanpos + 4;
if (is_octal(wc))
channel = channel << 3;
else
channel = channel << 2;
channel |= chan->span->offset;
if (debug & DEBUG_ECHOCAN) {
dev_notice(&wc->dev->dev,
"echocan: Card is %d, Channel is %d, Span is %d, offset is %d length %d\n",
wc->num, chan->chanpos, chan->span->offset,
channel, ecp->tap_length);
if (wc->vpm) {
if (is_octal(wc))
channel = channel << 3;
else
channel = channel << 2;
channel |= chan->span->offset;
if (debug & DEBUG_ECHOCAN)
dev_notice(&wc->dev->dev, "echocan: Card is %d, "
"Channel is %d, Span is %d, offset is %d "
"length %d\n", wc->num, chan->chanpos,
chan->span->offset, channel, ecp->tap_length);
vpm450m_setec(wc->vpm, channel, ecp->tap_length);
}
vpm450m_set_alaw_companding(wc->vpm, channel, alaw);
vpm450m_setec(wc->vpm, channel, ecp->tap_length);
return 0;
}
@@ -1164,23 +1165,23 @@ static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec
struct t4 *wc = chan->pvt;
int channel;
if (!wc->vpm)
return;
memset(ec, 0, sizeof(*ec));
channel = has_e1_span(wc) ? chan->chanpos : chan->chanpos + 4;
if (is_octal(wc))
channel = channel << 3;
else
channel = channel << 2;
channel |= chan->span->offset;
if (debug & DEBUG_ECHOCAN) {
dev_notice(&wc->dev->dev,
"echocan: Card is %d, Channel is %d, Span is %d, offset is %d length 0\n",
wc->num, chan->chanpos, chan->span->offset, channel);
if (wc->vpm) {
if (is_octal(wc))
channel = channel << 3;
else
channel = channel << 2;
channel |= chan->span->offset;
if (debug & DEBUG_ECHOCAN)
dev_notice(&wc->dev->dev, "echocan: Card is %d, "
"Channel is %d, Span is %d, offset is %d "
"length 0\n", wc->num, chan->chanpos,
chan->span->offset, channel);
vpm450m_setec(wc->vpm, channel, 0);
}
vpm450m_setec(wc->vpm, channel, 0);
}
#endif
@@ -1698,7 +1699,7 @@ static void t4_chan_set_sigcap(struct dahdi_span *span, int x)
}
static int
_t4_spanconfig(struct file *file, struct dahdi_span *span,
t4_spanconfig(struct file *file, struct dahdi_span *span,
struct dahdi_lineconfig *lc)
{
int i;
@@ -1713,11 +1714,8 @@ _t4_spanconfig(struct file *file, struct dahdi_span *span,
if (lc->sync < 0)
lc->sync = 0;
if (lc->sync > wc->numspans) {
dev_warn(&wc->dev->dev, "WARNING: Cannot set priority on span %d to %d. Please set to a number between 1 and %d\n",
span->spanno, lc->sync, wc->numspans);
if (lc->sync > wc->numspans)
lc->sync = 0;
}
/* remove this span number from the current sync sources, if there */
for(i = 0; i < wc->numspans; i++) {
@@ -1741,36 +1739,13 @@ _t4_spanconfig(struct file *file, struct dahdi_span *span,
/* If we're already running, then go ahead and apply the changes */
if (span->flags & DAHDI_FLAG_RUNNING)
return _t4_startup(file, span);
return t4_startup(file, span);
if (debug)
dev_info(&wc->dev->dev, "Done with spanconfig!\n");
return 0;
}
static int
t4_spanconfig(struct file *file, struct dahdi_span *span,
struct dahdi_lineconfig *lc)
{
int ret;
struct dahdi_device *const ddev = span->parent;
struct dahdi_span *s;
ret = _t4_spanconfig(file, span, lc);
/* Make sure all the spans have a basic configuration in case they are
* not all specified in the configuration files. */
lc->sync = 0;
list_for_each_entry(s, &ddev->spans, device_node) {
WARN_ON(!s->channels);
if (!s->channels)
continue;
if (!s->chans[0]->sigcap)
_t4_spanconfig(file, s, lc);
}
return ret;
}
static int
t4_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
{
@@ -1832,6 +1807,16 @@ t4_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
return 0;
}
static int t4_open(struct dahdi_chan *chan)
{
return 0;
}
static int t4_close(struct dahdi_chan *chan)
{
return 0;
}
static int set_span_devicetype(struct t4 *wc)
{
#ifdef VPM_SUPPORT
@@ -1884,33 +1869,6 @@ static void setup_chunks(struct t4 *wc, int which)
}
}
static int __t4_hardware_init_1(struct t4 *wc, unsigned int cardflags,
bool first_time);
static int __t4_hardware_init_2(struct t4 *wc, bool first_time);
static int t4_hardware_stop(struct t4 *wc);
static void t4_framer_reset(struct t4 *wc)
{
const bool first_time = false;
bool have_vpm = wc->vpm != NULL;
if (have_vpm) {
release_vpm450m(wc->vpm);
wc->vpm = NULL;
}
t4_hardware_stop(wc);
__t4_set_sclk_src(wc, WC_SELF, 0, 0);
__t4_hardware_init_1(wc, wc->devtype->flags, first_time);
__t4_hardware_init_2(wc, first_time);
if (have_vpm) {
t4_vpm_init(wc);
wc->dmactrl |= (wc->vpm) ? T4_VPM_PRESENT : 0;
t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
}
setup_chunks(wc, 0);
wc->lastindex = 0;
}
/**
* t4_serial_setup - Setup serial parameters and system interface.
* @wc: The card to configure.
@@ -1920,7 +1878,6 @@ static void t4_serial_setup(struct t4 *wc)
{
unsigned long flags;
unsigned int unit;
bool reset_required = false;
if (debug) {
dev_info(&wc->dev->dev,
@@ -1928,14 +1885,6 @@ static void t4_serial_setup(struct t4 *wc)
wc->numspans);
}
spin_lock_irqsave(&wc->reglock, flags);
reset_required = wc->reset_required > 0;
wc->reset_required = 0;
spin_unlock_irqrestore(&wc->reglock, flags);
if (reset_required)
t4_framer_reset(wc);
spin_lock_irqsave(&wc->reglock, flags);
/* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from
* channel 0 */
@@ -2086,7 +2035,6 @@ static void t4_span_assigned(struct dahdi_span *span)
struct t4 *wc = tspan->owner;
struct dahdi_span *pos;
unsigned int unassigned_spans = 0;
unsigned long flags;
/* We use this to make sure all the spans are assigned before
* running the serial setup. */
@@ -2095,22 +2043,14 @@ static void t4_span_assigned(struct dahdi_span *span)
++unassigned_spans;
}
if (0 == unassigned_spans) {
if (0 == unassigned_spans)
t4_serial_setup(wc);
set_bit(T4_CHECK_TIMING, &wc->checkflag);
spin_lock_irqsave(&wc->reglock, flags);
__t4_set_sclk_src(wc, WC_SELF, 0, 0);
spin_unlock_irqrestore(&wc->reglock, flags);
}
}
static void free_wc(struct t4 *wc)
{
unsigned int x, y;
flush_scheduled_work();
for (x = 0; x < ARRAY_SIZE(wc->tspans); x++) {
if (!wc->tspans[x])
continue;
@@ -2196,13 +2136,13 @@ static void t4_init_one_span(struct t4 *wc, struct t4_span *ts)
switch (ts->linemode) {
case T1:
ts->span.spantype = SPANTYPE_DIGITAL_T1;
ts->span.spantype = "T1";
break;
case E1:
ts->span.spantype = SPANTYPE_DIGITAL_E1;
ts->span.spantype = "E1";
break;
case J1:
ts->span.spantype = SPANTYPE_DIGITAL_J1;
ts->span.spantype = "J1";
break;
}
@@ -2251,58 +2191,40 @@ static void t4_init_one_span(struct t4 *wc, struct t4_span *ts)
/**
* t4_set_linemode - Allows user space to change the linemode before spans are assigned.
* @span: span on which to change the linemode.
* @linemode: A value from enumerated spantypes
* @linemode: Textual description of the new linemode.
*
* This callback is used to override the E1/T1 mode jumper settings and set
* the linemode on for each span. Called when the "spantype" attribute
* is written in sysfs under the dahdi_device.
*
*/
static int t4_set_linemode(struct dahdi_span *span, enum spantypes linemode)
static int t4_set_linemode(struct dahdi_span *span, const char *linemode)
{
struct t4_span *ts = container_of(span, struct t4_span, span);
struct t4 *wc = ts->owner;
int res = 0;
enum linemode mode;
const char *old_name;
static DEFINE_MUTEX(linemode_lock);
unsigned long flags;
dev_dbg(&wc->dev->dev, "Setting '%s' to '%s'\n", span->name,
dahdi_spantype2str(linemode));
dev_dbg(&wc->dev->dev, "Setting '%s' to '%s'\n", span->name, linemode);
if (span->spantype == linemode)
if (!strcasecmp(span->spantype, linemode))
return 0;
spin_lock_irqsave(&wc->reglock, flags);
wc->reset_required = 1;
spin_unlock_irqrestore(&wc->reglock, flags);
/* Do not allow the t1e1 member to be changed by multiple threads. */
mutex_lock(&linemode_lock);
old_name = dahdi_spantype2str(span->spantype);
switch (linemode) {
case SPANTYPE_DIGITAL_T1:
if (!strcasecmp(linemode, "t1")) {
dev_info(&wc->dev->dev,
"Changing from %s to T1 line mode.\n", old_name);
"Changing from %s to T1 line mode.\n", span->spantype);
mode = T1;
wc->t1e1 &= ~(1 << span->offset);
break;
case SPANTYPE_DIGITAL_E1:
} else if (!strcasecmp(linemode, "e1")) {
dev_info(&wc->dev->dev,
"Changing from %s to E1 line mode.\n", old_name);
"Changing from %s to E1 line mode.\n", span->spantype);
mode = E1;
wc->t1e1 |= (1 << span->offset);
break;
case SPANTYPE_DIGITAL_J1:
} else if (!strcasecmp(linemode, "j1")) {
dev_info(&wc->dev->dev,
"Changing from %s to J1 line mode.\n", old_name);
"Changing from %s to J1 line mode.\n", span->spantype);
mode = J1;
wc->t1e1 &= ~(1 << span->offset);
break;
default:
} else {
dev_err(&wc->dev->dev,
"Got invalid linemode %d from dahdi\n", linemode);
"'%s' is an unknown linemode.\n", linemode);
res = -EINVAL;
}
@@ -2312,7 +2234,6 @@ static int t4_set_linemode(struct dahdi_span *span, enum spantypes linemode)
dahdi_init_span(span);
}
mutex_unlock(&linemode_lock);
return res;
}
@@ -2324,6 +2245,8 @@ static const struct dahdi_span_ops t4_gen1_span_ops = {
.shutdown = t4_shutdown,
.rbsbits = t4_rbsbits,
.maint = t4_maint,
.open = t4_open,
.close = t4_close,
.ioctl = t4_ioctl,
.hdlc_hard_xmit = t4_hdlc_hard_xmit,
.assigned = t4_span_assigned,
@@ -2338,6 +2261,8 @@ static const struct dahdi_span_ops t4_gen2_span_ops = {
.shutdown = t4_shutdown,
.rbsbits = t4_rbsbits,
.maint = t4_maint,
.open = t4_open,
.close = t4_close,
.ioctl = t4_ioctl,
.hdlc_hard_xmit = t4_hdlc_hard_xmit,
.dacs = t4_dacs,
@@ -2376,13 +2301,13 @@ static void init_spans(struct t4 *wc)
"T%dXXP (PCI) Card %d Span %d", wc->numspans, wc->num, x+1);
switch (ts->linemode) {
case T1:
ts->span.spantype = SPANTYPE_DIGITAL_T1;
ts->span.spantype = "T1";
break;
case E1:
ts->span.spantype = SPANTYPE_DIGITAL_E1;
ts->span.spantype = "E1";
break;
case J1:
ts->span.spantype = SPANTYPE_DIGITAL_J1;
ts->span.spantype = "J1";
break;
}
@@ -2496,6 +2421,7 @@ static void __t4_set_sclk_src(struct t4 *wc, int mode, int master, int slave)
__t4_pci_out(wc, WC_DMACTRL, wc->dmactrl);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18))
static ssize_t t4_timing_master_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -2526,6 +2452,13 @@ static void remove_sysfs_files(struct t4 *wc)
&dev_attr_timing_master);
}
#else
static inline void create_sysfs_files(struct t4 *wc) { return; }
static inline void remove_sysfs_files(struct t4 *wc) { return; }
#endif /* LINUX_KERNEL > 2.6.18 */
static inline void __t4_update_timing(struct t4 *wc)
{
int i;
@@ -2710,7 +2643,7 @@ static void __t4_configure_t1(struct t4 *wc, int unit, int lineconfig, int txlev
if (lineconfig & DAHDI_CONFIG_AMI) {
line = "AMI";
/* workaround for errata #2 in ES v3 09-10-16 */
fmr0 = (is_octal(wc) || wc->falc31) ? 0xb0 : 0xa0;
fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
} else {
line = "B8ZS";
fmr0 = 0xf0;
@@ -2809,7 +2742,7 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
if (lineconfig & DAHDI_CONFIG_AMI) {
line = "AMI";
/* workaround for errata #2 in ES v3 09-10-16 */
fmr0 = (is_octal(wc) || wc->falc31) ? 0xb0 : 0xa0;
fmr0 = (wc->falc31) ? 0xb0 : 0xa0;
} else {
line = "HDB3";
fmr0 = 0xf0;
@@ -2870,10 +2803,6 @@ static void __t4_configure_e1(struct t4 *wc, int unit, int lineconfig)
__t4_framer_out(wc, unit, 0x17, 0x04 | imr3extra); /* IMR3: AIS */
__t4_framer_out(wc, unit, 0x18, 0x3f); /* IMR4: We care about slips on transmit */
__t4_framer_out(wc, unit, 0x2f, 0x00);
__t4_framer_out(wc, unit, 0x30, 0x00);
__t4_framer_out(wc, unit, 0x31, 0x00);
dev_info(&wc->dev->dev, "TE%dXXP: Span %d configured for %s/%s%s\n",
wc->numspans, unit + 1, framing, line, crc4);
}
@@ -2911,7 +2840,7 @@ static int t4_check_for_interrupts(struct t4 *wc)
return 0;
}
static int _t4_startup(struct file *file, struct dahdi_span *span)
static int t4_startup(struct file *file, struct dahdi_span *span)
{
#ifdef SUPPORT_GEN1
int i;
@@ -3044,21 +2973,6 @@ static int _t4_startup(struct file *file, struct dahdi_span *span)
return 0;
}
static int t4_startup(struct file *file, struct dahdi_span *span)
{
int ret;
struct dahdi_device *const ddev = span->parent;
struct dahdi_span *s;
ret = _t4_startup(file, span);
list_for_each_entry(s, &ddev->spans, device_node) {
if (!test_bit(DAHDI_FLAGBIT_RUNNING, &s->flags)) {
_t4_startup(file, s);
}
}
return ret;
}
#ifdef SUPPORT_GEN1
static inline void e1_check(struct t4 *wc, int span, int val)
{
@@ -3296,6 +3210,8 @@ static void t4_check_sigbits(struct t4 *wc, int span)
dev_notice(&wc->dev->dev, "Checking sigbits on span %d\n",
span + 1);
if (!(ts->span.flags & DAHDI_FLAG_RUNNING))
return;
if (E1 == ts->linemode) {
for (i = 0; i < 15; i++) {
a = t4_framer_in(wc, span, 0x71 + i);
@@ -3685,7 +3601,6 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
struct t4_span *ts = wc->tspans[span];
struct dahdi_chan *sigchan;
unsigned long flags;
bool recheck_sigbits = false;
/* 1st gen cards isn't used interrupts */
@@ -3711,8 +3626,6 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
ts->span.count.ebit += __t4_framer_in(wc, span, EBCL_T);
ts->span.count.be += __t4_framer_in(wc, span, BECL_T);
ts->span.count.prbs = __t4_framer_in(wc, span, FRS1_T);
if (DAHDI_RXSIG_INITIAL == ts->span.chans[0]->rxhooksig)
recheck_sigbits = true;
}
spin_unlock_irqrestore(&wc->reglock, flags);
@@ -3721,7 +3634,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
ts->span.count.errsec += 1;
}
if (isr0 & 0x08 || recheck_sigbits)
if (isr0)
t4_check_sigbits(wc, span);
if (E1 == ts->linemode) {
@@ -3735,7 +3648,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
}
if (!ts->span.alarms) {
if ((isr3 & 0x3) || (isr4 & 0xc0))
ts->span.count.timingslips++;
ts->span.timingslips++;
if (debug & DEBUG_MAIN) {
if (isr3 & 0x02)
@@ -3756,7 +3669,7 @@ static inline void t4_framer_interrupt(struct t4 *wc, int span)
wc->numspans, span + 1);
}
} else
ts->span.count.timingslips = 0;
ts->span.timingslips = 0;
spin_lock_irqsave(&wc->reglock, flags);
/* HDLC controller checks - receive side */
@@ -4048,15 +3961,9 @@ static void t4_increase_latency(struct t4 *wc, int newlatency)
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
static void t4_work_func(void *data)
static void t4_isr_bh(unsigned long data)
{
struct t4 *wc = data;
#else
static void t4_work_func(struct work_struct *work)
{
struct t4 *wc = container_of(work, struct t4, bh_work);
#endif
struct t4 *wc = (struct t4 *)data;
if (test_bit(T4_CHANGE_LATENCY, &wc->checkflag)) {
if (wc->needed_latency != wc->numbufs) {
@@ -4263,7 +4170,7 @@ static irqreturn_t _t4_interrupt_gen2(int irq, void *dev_id)
out:
if (unlikely(test_bit(T4_CHANGE_LATENCY, &wc->checkflag) || test_bit(T4_CHECK_VPM, &wc->checkflag)))
schedule_work(&wc->bh_work);
tasklet_schedule(&wc->t4_tlet);
#ifndef ENABLE_WORKQUEUES
__t4_pci_out(wc, WC_INTR, 0);
@@ -4357,7 +4264,7 @@ static void t4_vpm_init(struct t4 *wc)
laws[x] = 1;
}
vpm_capacity = get_vpm450m_capacity(&wc->dev->dev);
vpm_capacity = get_vpm450m_capacity(wc);
if (vpm_capacity != wc->numspans * 32) {
dev_info(&wc->dev->dev, "Disabling VPMOCT%03d. TE%dXXP"\
" requires a VPMOCT%03d", vpm_capacity,
@@ -4429,8 +4336,7 @@ static void t4_vpm_init(struct t4 *wc)
return;
}
wc->vpm = init_vpm450m(&wc->dev->dev, laws, wc->numspans, firmware);
if (!wc->vpm) {
if (!(wc->vpm = init_vpm450m(wc, laws, wc->numspans, firmware))) {
dev_notice(&wc->dev->dev, "VPM450: Failed to initialize\n");
if (firmware != &embedded_firmware)
release_firmware(firmware);
@@ -4752,6 +4658,12 @@ static int t8_update_firmware(struct t4 *wc, const struct firmware *fw,
const u32 BASE_ADDRESS = 0x00080000;
const u8 *data, *end;
size_t size = 0;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
u32 *pci_state;
pci_state = kzalloc(64 * sizeof(u32), GFP_KERNEL);
if (!pci_state)
return -ENOMEM;
#endif
/* Erase flash */
erase_half(wc);
@@ -4776,7 +4688,11 @@ static int t8_update_firmware(struct t4 *wc, const struct firmware *fw,
/* Reset te820 fpga after loading firmware */
dev_info(&wc->dev->dev, "Firmware load complete. Reseting device.\n");
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
res = pci_save_state(wc->dev, pci_state);
#else
res = pci_save_state(wc->dev);
#endif
if (res)
goto error_exit;
/* Set the fpga reset bits and clobber the remainder of the
@@ -4784,7 +4700,11 @@ static int t8_update_firmware(struct t4 *wc, const struct firmware *fw,
t4_pci_out(wc, WC_LEDS, 0xe0000000);
msleep(1000);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
pci_restore_state(wc->dev, pci_state);
#else
pci_restore_state(wc->dev);
#endif
/* Signal the driver to restart initialization.
* This will back out all initialization so far and
@@ -4792,6 +4712,9 @@ static int t8_update_firmware(struct t4 *wc, const struct firmware *fw,
return -EAGAIN;
error_exit:
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
kfree(pci_state);
#endif
return res;
}
@@ -4917,18 +4840,17 @@ cleanup:
return res;
}
static int
__t4_hardware_init_1(struct t4 *wc, unsigned int cardflags, bool first_time)
static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
{
unsigned int version;
int res;
version = t4_pci_in(wc, WC_VERSION);
if (is_octal(wc) && first_time) {
if (is_octal(wc)) {
dev_info(&wc->dev->dev, "Firmware Version: %01x.%02x\n",
(version & 0xf00) >> 8,
version & 0xff);
} else if (first_time) {
} else {
dev_info(&wc->dev->dev, "Firmware Version: %08x\n", version);
}
if (debug) {
@@ -4976,33 +4898,30 @@ __t4_hardware_init_1(struct t4 *wc, unsigned int cardflags, bool first_time)
t4_pci_out(wc, WC_INTR, 0x00000000);
/* Read T1/E1 status */
if (first_time) {
if (!strcasecmp("auto", default_linemode)) {
if (-1 == t1e1override) {
wc->t1e1 = (((t4_pci_in(wc, WC_LEDS)) &
0x0f00) >> 8);
wc->t1e1 &= 0xf;
if (is_octal(wc)) {
wc->t1e1 |= ((t4_pci_in(wc, WC_LEDS2)) &
0x0f00) >> 4;
}
} else {
dev_warn(&wc->dev->dev,
"'t1e1override' is deprecated. Please use 'default_linemode'.\n");
wc->t1e1 = t1e1override & 0xf;
if (!strcasecmp("auto", default_linemode)) {
if (-1 == t1e1override) {
wc->t1e1 = (((t4_pci_in(wc, WC_LEDS)) & 0x0f00) >> 8);
wc->t1e1 &= 0xf;
if (is_octal(wc)) {
wc->t1e1 |= ((t4_pci_in(wc, WC_LEDS2)) &
0x0f00) >> 4;
}
} else if (!strcasecmp("t1", default_linemode)) {
wc->t1e1 = 0;
} else if (!strcasecmp("e1", default_linemode)) {
wc->t1e1 = 0xff;
} else if (!strcasecmp("j1", default_linemode)) {
wc->t1e1 = 0;
j1mode = 1;
} else {
dev_err(&wc->dev->dev, "'%s' is an unknown linemode.\n",
default_linemode);
wc->t1e1 = 0;
dev_warn(&wc->dev->dev, "'t1e1override' is deprecated. "
"Please use 'default_linemode'.\n");
wc->t1e1 = t1e1override & 0xf;
}
} else if (!strcasecmp("t1", default_linemode)) {
wc->t1e1 = 0;
} else if (!strcasecmp("e1", default_linemode)) {
wc->t1e1 = 0xff;
} else if (!strcasecmp("j1", default_linemode)) {
wc->t1e1 = 0;
j1mode = 1;
} else {
dev_err(&wc->dev->dev, "'%s' is an unknown linemode.\n",
default_linemode);
wc->t1e1 = 0;
}
wc->order = ((t4_pci_in(wc, WC_LEDS)) & 0xf0000000) >> 28;
@@ -5031,12 +4950,7 @@ __t4_hardware_init_1(struct t4 *wc, unsigned int cardflags, bool first_time)
return 0;
}
static int t4_hardware_init_1(struct t4 *wc, unsigned int cardflags)
{
return __t4_hardware_init_1(wc, cardflags, true);
}
static int __t4_hardware_init_2(struct t4 *wc, bool first_time)
static int t4_hardware_init_2(struct t4 *wc)
{
int x;
unsigned int regval;
@@ -5068,14 +4982,13 @@ static int __t4_hardware_init_2(struct t4 *wc, bool first_time)
if (!is_octal(wc)) {
regval = t4_framer_in(wc, 0, 0x4a);
if (first_time && regval == 0x05) {
if (regval == 0x05) {
dev_info(&wc->dev->dev, "FALC Framer Version: 2.1 or "
"earlier\n");
} else if (regval == 0x20) {
if (first_time)
dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
dev_info(&wc->dev->dev, "FALC Framer Version: 3.1\n");
wc->falc31 = 1;
} else if (first_time) {
} else {
dev_info(&wc->dev->dev, "FALC Framer Version: Unknown "
"(VSTR = 0x%02x)\n", regval);
}
@@ -5095,24 +5008,14 @@ static int __t4_hardware_init_2(struct t4 *wc, bool first_time)
t4_pci_in(wc, x));
}
}
wc->gpio = 0x00000000;
t4_pci_out(wc, WC_GPIO, wc->gpio);
t4_gpio_setdir(wc, (1 << 17), (1 << 17));
t4_gpio_setdir(wc, (0xff), (0xff));
return 0;
}
static int t4_hardware_init_2(struct t4 *wc)
{
return __t4_hardware_init_2(wc, true);
}
static int __devinit t4_launch(struct t4 *wc)
{
int x;
int res;
unsigned long flags;
if (test_bit(DAHDI_FLAGBIT_REGISTERED, &wc->tspans[0]->span.flags))
return 0;
@@ -5144,18 +5047,17 @@ static int __devinit t4_launch(struct t4 *wc)
&wc->ddev->spans);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
INIT_WORK(&wc->bh_work, t4_work_func, wc);
#else
INIT_WORK(&wc->bh_work, t4_work_func);
#endif
res = dahdi_register_device(wc->ddev, &wc->dev->dev);
if (res) {
dev_err(&wc->dev->dev, "Failed to register with DAHDI.\n");
return res;
}
set_bit(T4_CHECK_TIMING, &wc->checkflag);
spin_lock_irqsave(&wc->reglock, flags);
__t4_set_sclk_src(wc, WC_SELF, 0, 0);
spin_unlock_irqrestore(&wc->reglock, flags);
tasklet_init(&wc->t4_tlet, t4_isr_bh, (unsigned long)wc);
return 0;
}
@@ -5369,6 +5271,10 @@ t4_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(&wc->dev->dev,
"Found a Wildcard: %s\n", wc->devtype->desc);
}
wc->gpio = 0x00000000;
t4_pci_out(wc, WC_GPIO, wc->gpio);
t4_gpio_setdir(wc, (1 << 17), (1 << 17));
t4_gpio_setdir(wc, (0xff), (0xff));
#ifdef VPM_SUPPORT
if (!wc->vpm) {
@@ -5526,11 +5432,13 @@ static DEFINE_PCI_DEVICE_TABLE(t4_pci_tbl) =
{ 0, }
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
static void _t4_shutdown(struct pci_dev *pdev)
{
struct t4 *wc = pci_get_drvdata(pdev);
t4_hardware_stop(wc);
}
#endif
static int t4_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -5541,7 +5449,9 @@ static struct pci_driver t4_driver = {
.name = "wct4xxp",
.probe = t4_init_one_retry,
.remove = __devexit_p(t4_remove_one),
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
.shutdown = _t4_shutdown,
#endif
.suspend = t4_suspend,
.id_table = t4_pci_tbl,
};

View File

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

View File

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

View File

@@ -131,6 +131,13 @@ struct t4_reg {
unsigned int val;
};
#define T4_CHECK_VPM 0
#define T4_LOADING_FW 1
#define T4_STOP_DMA 2
#define T4_CHECK_TIMING 3
#define T4_CHANGE_LATENCY 4
#define T4_IGNORE_LATENCY 5
#define WCT4_GET_REGS _IOW(DAHDI_CODE, 60, struct t4_regs)
#define WCT4_GET_REG _IOW(DAHDI_CODE, 61, struct t4_reg)
#define WCT4_SET_REG _IOW(DAHDI_CODE, 62, struct t4_reg)

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -31,7 +31,6 @@
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/io.h>
#include "proslic.h"
@@ -2144,7 +2143,7 @@ static int wctdm_ioctl(struct dahdi_chan *chan, unsigned int cmd, unsigned long
}
static int _wctdm_open(struct dahdi_chan *chan)
static int wctdm_open(struct dahdi_chan *chan)
{
struct wctdm *wc = chan->pvt;
if (!(wc->cardflag & (1 << (chan->chanpos - 1))))
@@ -2155,16 +2154,6 @@ static int _wctdm_open(struct dahdi_chan *chan)
return 0;
}
static int wctdm_open(struct dahdi_chan *chan)
{
unsigned long flags;
int res;
spin_lock_irqsave(&chan->lock, flags);
res = _wctdm_open(chan);
spin_unlock_irqrestore(&chan->lock, flags);
return res;
}
static inline struct wctdm *wctdm_from_span(struct dahdi_span *span)
{
return container_of(span, struct wctdm, span);

View File

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

View File

@@ -7,7 +7,7 @@
* Support for Hx8 by Andrew Kohlsmith <akohlsmith@mixdown.ca> and Matthew
* Fredrickson <creslin@digium.com>
*
* Copyright (C) 2005 - 2012 Digium, Inc.
* Copyright (C) 2005 - 2011 Digium, Inc.
* All rights reserved.
*
* Sections for QRV cards written by Jim Dixon <jim@lambdatel.com>
@@ -55,7 +55,6 @@ Tx Gain - W/Pre-Emphasis: -23.99 to 0.00 db
#include <asm/semaphore.h>
#endif
#include <linux/crc32.h>
#include <linux/slab.h>
#include <stdbool.h>
@@ -1962,26 +1961,19 @@ wctdm_check_battery_lost(struct wctdm *wc, struct wctdm_module *const mod)
battery present or unknown, debounce timer (going to battery lost)
*/
switch (fxo->battery_state) {
case BATTERY_DEBOUNCING_PRESENT_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_PRESENT:
case BATTERY_DEBOUNCING_PRESENT_ALARM: /* intentional drop through */
/* we were going to BATTERY_PRESENT, but
* battery was lost again. */
fxo->battery_state = BATTERY_LOST;
break;
case BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_LOST_ALARM;
fxo->battdebounce_timer = wc->framecount +
battalarm - battdebounce;
break;
case BATTERY_UNKNOWN:
mod_hooksig(wc, mod, DAHDI_RXSIG_ONHOOK);
case BATTERY_PRESENT:
fxo->battery_state = BATTERY_DEBOUNCING_LOST;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM:
case BATTERY_DEBOUNCING_LOST: /* Intentional drop through */
case BATTERY_DEBOUNCING_LOST:
if (time_after(wc->framecount, fxo->battdebounce_timer)) {
if (debug) {
dev_info(&wc->vb.pdev->dev,
@@ -2030,8 +2022,7 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod)
struct fxo *const fxo = &mod->mod.fxo;
switch (fxo->battery_state) {
case BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM:
case BATTERY_DEBOUNCING_PRESENT: /* intentional drop through */
case BATTERY_DEBOUNCING_PRESENT:
if (time_after(wc->framecount, fxo->battdebounce_timer)) {
if (debug) {
dev_info(&wc->vb.pdev->dev,
@@ -2070,16 +2061,10 @@ wctdm_check_battery_present(struct wctdm *wc, struct wctdm_module *const mod)
break;
case BATTERY_PRESENT:
break;
case BATTERY_DEBOUNCING_LOST_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM;
fxo->battdebounce_timer = wc->framecount + battdebounce;
break;
case BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM:
fxo->battery_state = BATTERY_DEBOUNCING_PRESENT_ALARM;
fxo->battdebounce_timer = wc->framecount +
battalarm - battdebounce;
break;
case BATTERY_DEBOUNCING_LOST:
case BATTERY_DEBOUNCING_LOST_ALARM:
/* we were going to BATTERY_LOST, but battery appeared again,
* so clear the debounce timer */
fxo->battery_state = BATTERY_PRESENT;
break;
case BATTERY_UNKNOWN:
@@ -3101,8 +3086,6 @@ wctdm_init_voicedaa(struct wctdm *wc, struct wctdm_module *mod,
spin_unlock_irqrestore(&wc->reglock, flags);
msleep(20);
memset(&mod->mod.fxo, 0, sizeof(mod->mod.fxo));
if (!sane && wctdm_voicedaa_insane(wc, mod))
return -2;
@@ -3247,7 +3230,8 @@ wctdm_init_proslic(struct wctdm *wc, struct wctdm_module *const mod,
return -2;
/* Initialize VMWI settings */
memset(fxs, 0, sizeof(*fxs));
memset(&(fxs->vmwisetting), 0, sizeof(fxs->vmwisetting));
fxs->vmwi_linereverse = 0;
/* By default, don't send on hook */
if (!reversepolarity != !fxs->reversepolarity)
@@ -4386,6 +4370,32 @@ wctdm_chanconfig(struct file *file, struct dahdi_chan *chan, int sigtype)
return wctdm_wait_for_ready(wc);
}
/*
* wctdm24xxp_assigned - Called when span is assigned.
* @span: The span that is now assigned.
*
* This function is called by the core of DAHDI after the span number and
* channel numbers have been assigned.
*
*/
static void wctdm24xxp_assigned(struct dahdi_span *span)
{
struct dahdi_span *s;
struct dahdi_device *ddev = span->parent;
struct wctdm *wc = NULL;
list_for_each_entry(s, &ddev->spans, device_node) {
wc = (container_of(s, struct wctdm_span, span))->wc;
if (!test_bit(DAHDI_FLAGBIT_REGISTERED, &s->flags))
return;
}
if (wc) {
WARN_ON(0 == wc->not_ready);
--wc->not_ready;
}
}
static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.owner = THIS_MODULE,
.hooksig = wctdm_hooksig,
@@ -4395,6 +4405,7 @@ static const struct dahdi_span_ops wctdm24xxp_analog_span_ops = {
.watchdog = wctdm_watchdog,
.chanconfig = wctdm_chanconfig,
.dacs = wctdm_dacs,
.assigned = wctdm24xxp_assigned,
#ifdef VPM_SUPPORT
.enable_hw_preechocan = wctdm_enable_hw_preechocan,
.disable_hw_preechocan = wctdm_disable_hw_preechocan,
@@ -4413,6 +4424,7 @@ static const struct dahdi_span_ops wctdm24xxp_digital_span_ops = {
.spanconfig = b400m_spanconfig,
.chanconfig = b400m_chanconfig,
.dacs = wctdm_dacs,
.assigned = wctdm24xxp_assigned,
#ifdef VPM_SUPPORT
.enable_hw_preechocan = wctdm_enable_hw_preechocan,
.disable_hw_preechocan = wctdm_disable_hw_preechocan,
@@ -4513,11 +4525,10 @@ wctdm_init_span(struct wctdm *wc, int spanno, int chanoffset, int chancount,
s->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4;
s->span.linecompat |= DAHDI_CONFIG_ESF | DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
s->span.linecompat |= DAHDI_CONFIG_NTTE | DAHDI_CONFIG_TERM;
s->span.spantype = SPANTYPE_DIGITAL_BRI_TE;
s->span.spantype = "TE";
} else {
s->span.ops = &wctdm24xxp_analog_span_ops;
s->span.flags = DAHDI_FLAG_RBS;
s->span.spantype = SPANTYPE_ANALOG_MIXED;
/* analog sigcap handled in fixup_analog_span() */
}
@@ -5925,9 +5936,6 @@ __wctdm_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return -1;
}
WARN_ON(wc->not_ready <= 0);
--wc->not_ready;
dev_info(&wc->vb.pdev->dev,
"Found a %s: %s (%d BRI spans, %d analog %s)\n",
(is_hx8(wc)) ? "Hybrid card" : "Wildcard TDM",
@@ -6057,11 +6065,13 @@ static DEFINE_PCI_DEVICE_TABLE(wctdm_pci_tbl) = {
{ 0 }
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
static void wctdm_shutdown(struct pci_dev *pdev)
{
struct wctdm *wc = pci_get_drvdata(pdev);
voicebus_quiesce(&wc->vb);
}
#endif
MODULE_DEVICE_TABLE(pci, wctdm_pci_tbl);
@@ -6074,7 +6084,9 @@ static struct pci_driver wctdm_driver = {
.name = "wctdm24xxp",
.probe = wctdm_init_one,
.remove = __devexit_p(wctdm_remove_one),
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
.shutdown = wctdm_shutdown,
#endif
.suspend = wctdm_suspend,
.id_table = wctdm_pci_tbl,
};

View File

@@ -106,11 +106,9 @@ struct calregs {
enum battery_state {
BATTERY_UNKNOWN = 0,
BATTERY_DEBOUNCING_PRESENT,
BATTERY_DEBOUNCING_PRESENT_FROM_LOST_ALARM,
BATTERY_DEBOUNCING_PRESENT_ALARM,
BATTERY_PRESENT,
BATTERY_DEBOUNCING_LOST,
BATTERY_DEBOUNCING_LOST_FROM_PRESENT_ALARM,
BATTERY_DEBOUNCING_LOST_ALARM,
BATTERY_LOST,
};

View File

@@ -25,7 +25,6 @@
#include <linux/ppp_defs.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
#define FAST_HDLC_NEED_TABLES
#include <dahdi/kernel.h>
@@ -2151,9 +2150,7 @@ static int b400m_set_ntte(struct b400m_span *bspan, int te_mode, int term_on)
int all_modes = 0, all_terms = 0;
int i;
bspan->wspan->span.spantype = (te_mode > 0)
? SPANTYPE_DIGITAL_BRI_TE
: SPANTYPE_DIGITAL_BRI_NT;
bspan->wspan->span.spantype = (te_mode > 0) ? "TE" : "NT";
bspan->te_mode = te_mode;
bspan->term_on = term_on;

View File

@@ -31,7 +31,6 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <dahdi/kernel.h>
@@ -225,7 +224,7 @@ static inline void __select_control(struct t1 *wc)
}
}
static int _t1xxp_open(struct dahdi_chan *chan)
static int t1xxp_open(struct dahdi_chan *chan)
{
struct t1 *wc = chan->pvt;
if (wc->dead)
@@ -235,16 +234,6 @@ static int _t1xxp_open(struct dahdi_chan *chan)
return 0;
}
static int t1xxp_open(struct dahdi_chan *chan)
{
unsigned long flags;
int res;
spin_lock_irqsave(&chan->lock, flags);
res = _t1xxp_open(chan);
spin_unlock_irqrestore(&chan->lock, flags);
return res;
}
static int __control_set_reg(struct t1 *wc, int reg, unsigned char val)
{
__select_control(wc);
@@ -1011,12 +1000,12 @@ static int t1xxp_software_init(struct t1 *wc)
else
wc->span.channels = 31;
wc->span.deflaw = DAHDI_LAW_ALAW;
wc->span.spantype = SPANTYPE_DIGITAL_E1;
wc->span.spantype = "E1";
wc->span.linecompat = DAHDI_CONFIG_HDB3 | DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
} else {
wc->span.channels = 24;
wc->span.deflaw = DAHDI_LAW_MULAW;
wc->span.spantype = SPANTYPE_DIGITAL_T1;
wc->span.spantype = "T1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS | DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
}
wc->span.chans = wc->chans;

View File

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

View File

@@ -8,7 +8,7 @@
* Matthew Fredrickson <creslin@digium.com>
* William Meadows <wmeadows@digium.com>
*
* Copyright (C) 2007-2012, Digium, Inc.
* Copyright (C) 2007-2011, Digium, Inc.
*
* All rights reserved.
*
@@ -40,7 +40,6 @@
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <stdbool.h>
#include <dahdi/kernel.h>
@@ -659,17 +658,6 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd)
might_sleep();
if (test_bit(IOERROR, &wc->bit_flags)) {
spin_lock_irqsave(&wc->reglock, flags);
list_del_init(&cmd->node);
spin_unlock_irqrestore(&wc->reglock, flags);
if (printk_ratelimit()) {
dev_warn(&wc->vb.pdev->dev,
"Timeout in %s\n", __func__);
}
return -EIO;
}
ret = wait_for_completion_interruptible_timeout(&cmd->complete, HZ*10);
if (unlikely(!ret)) {
spin_lock_irqsave(&wc->reglock, flags);
@@ -678,13 +666,13 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd)
* can go ahead and free it right away. */
list_del_init(&cmd->node);
spin_unlock_irqrestore(&wc->reglock, flags);
free_cmd(wc, cmd);
if (-ERESTARTSYS != ret) {
if (printk_ratelimit()) {
dev_warn(&wc->vb.pdev->dev,
"Timeout in %s\n", __func__);
}
ret = -EIO;
set_bit(IOERROR, &wc->bit_flags);
}
return ret;
} else {
@@ -695,6 +683,7 @@ static int __t1_getresult(struct t1 *wc, struct command *cmd)
ret = wait_for_completion_timeout(&cmd->complete, HZ*2);
WARN_ON(!ret);
ret = cmd->data;
free_cmd(wc, cmd);
return ret;
}
}
@@ -852,75 +841,6 @@ static void free_wc(struct t1 *wc)
kfree(wc);
}
/**
* t1_reset_registers - Put register back to their default values
*
* Since the card does not have an ability to reset just the framer
* specifically, we need to write all the default values to the framer.
*
*/
static void t1_reset_registers(struct t1 *wc)
{
int i;
struct t1_reg {
u8 address;
u8 value;
} __attribute__((packed));
struct t1_reg *reg;
static struct t1_reg DEFAULT_REGS[] = {
{0x00, 0x7d}, {0x01, 0x7d}, {0x02, 0x00}, {0x03, 0x00},
{0x04, 0xfd}, {0x05, 0xff}, {0x06, 0xff}, {0x07, 0xff},
{0x08, 0x05}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00},
{0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
{0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00},
{0x14, 0xff}, {0x15, 0xff}, {0x16, 0xff}, {0x17, 0xff},
{0x18, 0xff}, {0x19, 0xff}, {0x1a, 0x00}, {0x1b, 0x00},
{0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
{0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x04},
{0x24, 0x00}, {0x25, 0x05}, {0x26, 0x7b}, {0x27, 0x03},
{0x28, 0x40}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00},
{0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00},
{0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
{0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x80},
{0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x20}, {0x3b, 0x00},
{0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x0a}, {0x3f, 0x00},
{0x40, 0x04}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00},
{0x44, 0x30}, {0x45, 0x00}, {0x46, 0xc0}, {0x47, 0xff},
{0x48, 0x00}, {0x49, 0x1c}, {0x4a, 0x05}, {0x4b, 0x03},
{0x4c, 0xa3}, {0x4d, 0x28}, {0x4e, 0x00}, {0x4f, 0xc0},
{0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00},
{0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00},
{0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00},
{0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00},
{0x60, 0x00}, {0x61, 0x20}, {0x62, 0x00}, {0x63, 0x00},
{0x64, 0x5a}, {0x65, 0x02}, {0x66, 0x00}, {0x67, 0x00},
{0x68, 0x10}, {0x69, 0x09}, {0x6a, 0x00}, {0x6b, 0x03},
{0x6c, 0x00}, {0x6d, 0xc0}, {0x6e, 0x40}, {0x6f, 0x00},
{0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00},
{0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00},
{0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00},
{0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00},
{0x80, 0x00}, {0x81, 0x22}, {0x82, 0x65}, {0x83, 0x35},
{0x84, 0x31}, {0x85, 0x60}, {0x86, 0x03}, {0x87, 0x00},
{0x88, 0x00}, {0x89, 0x00}, {0x8a, 0x00}, {0x8b, 0x00},
{0x8c, 0x00}, {0x8d, 0x00}, {0x8e, 0x00}, {0x8f, 0x00},
{0x90, 0x00}, {0x91, 0x00}, {0x92, 0x00}, {0x93, 0x18},
{0x94, 0xfb}, {0x95, 0x0b}, {0x96, 0x00}, {0x97, 0x0b},
{0x98, 0xdb}, {0x99, 0xdf}, {0x9a, 0x48}, {0x9b, 0x00},
{0x9c, 0x3f}, {0x9d, 0x3f}, {0x9e, 0x77}, {0x9f, 0x77},
{0xa0, 0x00}, {0xa1, 0xff}, {0xa2, 0xff}, {0xa3, 0xff},
{0xa4, 0x00}, {0xa5, 0x00}, {0xa6, 0x00}, {0xa7, 0x00},
{0xa8, 0x00}
};
for (i = 0; i < ARRAY_SIZE(DEFAULT_REGS); ++i) {
reg = &DEFAULT_REGS[i];
t1_setreg(wc, reg->address, reg->value);
}
/* Flush previous writes. */
t1_getreg(wc, 0x1d);
}
static void t4_serial_setup(struct t1 *wc)
{
t1_setreg(wc, 0x85, 0xe0); /* GPC1: Multiplex mode enabled, FSC is output, active low, RCLK from channel 0 */
@@ -974,7 +894,7 @@ static void t1_configure_t1(struct t1 *wc, int lineconfig, int txlevel)
fmr2 = 0x20; /* FMR2: no payload loopback, don't auto yellow alarm */
if (SPANTYPE_DIGITAL_J1 == wc->span.spantype)
if (!strcasecmp("j1", wc->span.spantype))
fmr4 = 0x1c;
else
fmr4 = 0x0c; /* FMR4: Lose sync on 2 out of 5 framing bits, auto resync */
@@ -1014,7 +934,7 @@ static void t1_configure_t1(struct t1 *wc, int lineconfig, int txlevel)
t1_setreg(wc, 0x38, 0x0a); /* PCD: LOS after 176 consecutive "zeros" */
t1_setreg(wc, 0x39, 0x15); /* PCR: 22 "ones" clear LOS */
if (SPANTYPE_DIGITAL_J1 == wc->span.spantype)
if (!strcasecmp("j1", wc->span.spantype))
t1_setreg(wc, 0x24, 0x80); /* J1 overide */
/* Generate pulse mask for T1 */
@@ -2028,21 +1948,21 @@ static int t1_software_init(struct t1 *wc, enum linemode type)
switch (type) {
case E1:
wc->span.channels = 31;
wc->span.spantype = SPANTYPE_DIGITAL_E1;
wc->span.spantype = "E1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_HDB3 |
DAHDI_CONFIG_CCS | DAHDI_CONFIG_CRC4;
wc->span.deflaw = DAHDI_LAW_ALAW;
break;
case T1:
wc->span.channels = 24;
wc->span.spantype = SPANTYPE_DIGITAL_T1;
wc->span.spantype = "T1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS |
DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
wc->span.deflaw = DAHDI_LAW_MULAW;
break;
case J1:
wc->span.channels = 24;
wc->span.spantype = SPANTYPE_DIGITAL_J1;
wc->span.spantype = "J1";
wc->span.linecompat = DAHDI_CONFIG_AMI | DAHDI_CONFIG_B8ZS |
DAHDI_CONFIG_D4 | DAHDI_CONFIG_ESF;
wc->span.deflaw = DAHDI_LAW_MULAW;
@@ -2059,7 +1979,7 @@ static int t1_software_init(struct t1 *wc, enum linemode type)
return -ENOMEM;
t1_info(wc, "Setting up global serial parameters for %s\n",
dahdi_spantype2str(wc->span.spantype));
wc->span.spantype);
t4_serial_setup(wc);
set_bit(DAHDI_FLAGBIT_RBS, &wc->span.flags);
@@ -2093,13 +2013,13 @@ error_exit:
* DAHDI).
*
*/
static int t1xxp_set_linemode(struct dahdi_span *span, enum spantypes linemode)
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 (span->spantype == linemode)
if (!strcasecmp(span->spantype, linemode))
return 0;
res = t1_wait_for_ready(wc);
@@ -2109,35 +2029,28 @@ static int t1xxp_set_linemode(struct dahdi_span *span, enum spantypes linemode)
/* Stop the processing of the channels since we're going to change
* them. */
clear_bit(INITIALIZED, &wc->bit_flags);
synchronize_irq(wc->vb.pdev->irq);
smp_mb__after_clear_bit();
del_timer_sync(&wc->timer);
flush_workqueue(wc->wq);
t1_reset_registers(wc);
switch (linemode) {
case SPANTYPE_DIGITAL_T1:
if (!strcasecmp(linemode, "t1")) {
dev_info(&wc->vb.pdev->dev,
"Changing from %s to T1 line mode.\n",
dahdi_spantype2str(wc->span.spantype));
wc->span.spantype);
res = t1_software_init(wc, T1);
break;
case SPANTYPE_DIGITAL_E1:
} else if (!strcasecmp(linemode, "e1")) {
dev_info(&wc->vb.pdev->dev,
"Changing from %s to E1 line mode.\n",
dahdi_spantype2str(wc->span.spantype));
wc->span.spantype);
res = t1_software_init(wc, E1);
break;
case SPANTYPE_DIGITAL_J1:
} else if (!strcasecmp(linemode, "j1")) {
dev_info(&wc->vb.pdev->dev,
"Changing from %s to E1 line mode.\n",
dahdi_spantype2str(wc->span.spantype));
wc->span.spantype);
res = t1_software_init(wc, J1);
default:
} else {
dev_err(&wc->vb.pdev->dev,
"Got invalid linemode '%s' from dahdi\n",
dahdi_spantype2str(linemode));
"'%s' is an unknown linemode.\n", linemode);
res = -EINVAL;
}
@@ -2289,32 +2202,27 @@ static void t1_check_alarms(struct t1 *wc)
/* Detect loopup code if we're not sending one */
if ((!wc->span.mainttimer) && (d & 0x08)) {
/* Loop-up code detected */
if ((++wc->loopupcnt > 80) &&
(wc->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
if ((wc->span.maintstat != DAHDI_MAINT_REMOTELOOP)) {
t1_notice(wc, "Loopup detected,"\
" enabling remote loop\n");
t1_setreg(wc, 0x36, 0x08); /* LIM0: Disable any local loop */
t1_setreg(wc, 0x37, 0xf6); /* LIM1: Enable remote loop */
wc->span.maintstat = DAHDI_MAINT_REMOTELOOP;
}
} else {
} else
wc->loopupcnt = 0;
}
/* Same for loopdown code */
if ((!wc->span.mainttimer) && (d & 0x10)) {
/* Loop-down code detected */
if ((++wc->loopdowncnt > 80) &&
(wc->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
if ((wc->span.maintstat == DAHDI_MAINT_REMOTELOOP)) {
t1_notice(wc, "Loopdown detected,"\
" disabling remote loop\n");
t1_setreg(wc, 0x36, 0x08); /* LIM0: Disable any local loop */
t1_setreg(wc, 0x37, 0xf0); /* LIM1: Disable remote loop */
wc->span.maintstat = DAHDI_MAINT_NONE;
}
} else {
} else
wc->loopdowncnt = 0;
}
}
if (wc->span.lineconfig & DAHDI_CONFIG_NOTOPEN) {
@@ -2938,7 +2846,13 @@ static int __devinit te12xp_init_one(struct pci_dev *pdev, const struct pci_devi
spin_lock_init(&wc->reglock);
INIT_LIST_HEAD(&wc->active_cmds);
INIT_LIST_HEAD(&wc->pending_cmds);
# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
wc->timer.function = te12xp_timer;
wc->timer.data = (unsigned long)wc;
init_timer(&wc->timer);
# else
setup_timer(&wc->timer, te12xp_timer, (unsigned long)wc);
# endif
# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
INIT_WORK(&wc->timer_work, timer_work_func, wc);
@@ -3118,11 +3032,13 @@ static DEFINE_PCI_DEVICE_TABLE(te12xp_pci_tbl) = {
{ 0 }
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
static void te12xp_shutdown(struct pci_dev *pdev)
{
struct t1 *wc = pci_get_drvdata(pdev);
voicebus_quiesce(&wc->vb);
}
#endif
static int te12xp_suspend(struct pci_dev *pdev, pm_message_t state)
{
@@ -3135,7 +3051,9 @@ static struct pci_driver te12xp_driver = {
.name = "wcte12xp",
.probe = te12xp_init_one,
.remove = __devexit_p(te12xp_remove_one),
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 12)
.shutdown = te12xp_shutdown,
#endif
.suspend = te12xp_suspend,
.id_table = te12xp_pci_tbl,
};

View File

@@ -114,7 +114,6 @@ struct t1 {
#define INITIALIZED 1
#define SHUTDOWN 2
#define READY 3
#define IOERROR 4
unsigned long bit_flags;
unsigned long alarmtimer;
unsigned char ledstate;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -33,22 +33,21 @@
static const char rcsid[] = "$Id$";
DEF_PARM(charp, initdir, "/usr/share/dahdi", 0644,
"The directory of card initialization scripts");
DEF_PARM(charp,initdir, "/usr/share/dahdi", 0644, "The directory of card initialization scripts");
#define CHIP_REGISTERS "chipregs"
extern int debug;
extern int debug;
/*---------------- GLOBAL PROC handling -----------------------------------*/
static int send_magic_request(xbus_t *xbus, unsigned unit, xportno_t portno,
bool eoftx)
static int send_magic_request(xbus_t *xbus,
unsigned unit, xportno_t portno, bool eoftx)
{
xframe_t *xframe;
xpacket_t *pack;
reg_cmd_t *reg_cmd;
int ret;
xframe_t *xframe;
xpacket_t *pack;
reg_cmd_t *reg_cmd;
int ret;
/*
* Zero length multibyte is legal and has special meaning for the
@@ -67,210 +66,203 @@ static int send_magic_request(xbus_t *xbus, unsigned unit, xportno_t portno,
dump_xframe(__func__, xbus, xframe, debug);
ret = send_cmd_frame(xbus, xframe);
if (ret < 0)
PORT_ERR(xbus, unit, portno, "%s: failed sending xframe\n",
__func__);
PORT_ERR(xbus, unit, portno,
"%s: failed sending xframe\n", __func__);
return ret;
}
static int parse_hexbyte(const char *buf)
{
char *endp;
unsigned val;
char *endp;
unsigned val;
val = simple_strtoul(buf, &endp, 16);
if (*endp != '\0' || val > 0xFF)
if(*endp != '\0' || val > 0xFF)
return -EBADR;
return (__u8)val;
return (byte)val;
}
static int execute_chip_command(xpd_t *xpd, const int argc, char *argv[])
{
int argno;
char num_args;
int portno;
bool writing;
int op; /* [W]rite, [R]ead */
int addr_mode; /* [D]irect, [I]ndirect, [Mm]ulti */
bool do_subreg = 0;
int regnum;
int subreg;
int data_low;
bool do_datah;
int data_high;
int ret = -EBADR;
int argno;
char num_args;
int portno;
bool writing;
int op; /* [W]rite, [R]ead */
int addr_mode; /* [D]irect, [I]ndirect, [Mm]ulti */
bool do_subreg = 0;
int regnum;
int subreg;
int data_low;
bool do_datah;
int data_high;
int ret = -EBADR;
num_args = 2; /* port + operation */
if (argc < num_args) {
num_args = 2; /* port + operation */
if(argc < num_args) {
XPD_ERR(xpd, "Not enough arguments (%d)\n", argc);
XPD_ERR(xpd,
"Any Command is composed of at least %d words "
"(got only %d)\n",
num_args, argc);
"Any Command is composed of at least %d words (got only %d)\n",
num_args, argc);
goto out;
}
/* Process the arguments */
argno = 0;
if (strcmp(argv[argno], "*") == 0) {
if(strcmp(argv[argno], "*") == 0) {
portno = PORT_BROADCAST;
//XPD_DBG(REGS, xpd, "Port broadcast\n");
} else {
portno = parse_hexbyte(argv[argno]);
if (portno < 0 || portno >= 8) {
if(portno < 0 || portno >= 8) {
XPD_ERR(xpd, "Illegal port number '%s'\n", argv[argno]);
goto out;
}
//XPD_DBG(REGS, xpd, "Port is %d\n", portno);
}
argno++;
if (strlen(argv[argno]) != 2) {
if(strlen(argv[argno]) != 2) {
XPD_ERR(xpd, "Wrong operation codes '%s'\n", argv[argno]);
goto out;
}
op = argv[argno][0];
switch (op) {
case 'W':
writing = 1;
num_args++; /* data low */
//XPD_DBG(REGS, xpd, "WRITING\n");
break;
case 'R':
writing = 0;
//XPD_DBG(REGS, xpd, "READING\n");
break;
default:
XPD_ERR(xpd, "Unknown operation type '%c'\n", op);
goto out;
switch(op) {
case 'W':
writing = 1;
num_args++; /* data low */
//XPD_DBG(REGS, xpd, "WRITING\n");
break;
case 'R':
writing = 0;
//XPD_DBG(REGS, xpd, "READING\n");
break;
default:
XPD_ERR(xpd, "Unknown operation type '%c'\n", op);
goto out;
}
addr_mode = argv[argno][1];
switch (addr_mode) {
case 'I':
XPD_NOTICE(xpd,
"'I' is deprecated in register commands. "
"Use 'S' instead.\n");
/* fall through */
case 'S':
do_subreg = 1;
num_args += 2; /* register + subreg */
//XPD_DBG(REGS, xpd, "SUBREG\n");
break;
case 'D':
do_subreg = 0;
num_args++; /* register */
//XPD_DBG(REGS, xpd, "DIRECT\n");
break;
case 'M':
case 'm':
if (op != 'W') {
XPD_ERR(xpd,
"Can use Multibyte (%c) only with op 'W'\n",
addr_mode);
switch(addr_mode) {
case 'I':
XPD_NOTICE(xpd, "'I' is deprecated in register commands. Use 'S' instead.\n");
/* fall through */
case 'S':
do_subreg = 1;
num_args += 2; /* register + subreg */
//XPD_DBG(REGS, xpd, "SUBREG\n");
break;
case 'D':
do_subreg = 0;
num_args++; /* register */
//XPD_DBG(REGS, xpd, "DIRECT\n");
break;
case 'M':
case 'm':
if(op != 'W') {
XPD_ERR(xpd,
"Can use Multibyte (%c) only with op 'W'\n", addr_mode);
goto out;
}
num_args--; /* No data low */
//XPD_DBG(REGS, xpd, "Multibyte (%c)\n", addr_mode);
break;
default:
XPD_ERR(xpd, "Unknown addressing type '%c'\n", addr_mode);
goto out;
}
num_args--; /* No data low */
//XPD_DBG(REGS, xpd, "Multibyte (%c)\n", addr_mode);
break;
default:
XPD_ERR(xpd, "Unknown addressing type '%c'\n", addr_mode);
goto out;
}
if (argv[argno][2] != '\0') {
if(argv[argno][2] != '\0') {
XPD_ERR(xpd, "Bad operation field '%s'\n", argv[argno]);
goto out;
}
if (argc < num_args) {
if(argc < num_args) {
XPD_ERR(xpd,
"Command \"%s\" is composed of at least %d words "
"(got only %d)\n",
argv[argno], num_args, argc);
"Command \"%s\" is composed of at least %d words (got only %d)\n",
argv[argno], num_args, argc);
goto out;
}
argno++;
if (addr_mode == 'M' || addr_mode == 'm') {
if (argno < argc) {
if(addr_mode == 'M' || addr_mode == 'm') {
if(argno < argc) {
XPD_ERR(xpd,
"Magic-Multibyte(%c) with %d extra arguments\n",
addr_mode, argc - argno);
"Magic-Multibyte(%c) with %d extra arguments\n",
addr_mode, argc - argno);
goto out;
}
ret =
send_magic_request(xpd->xbus, xpd->addr.unit, portno,
addr_mode == 'm');
ret = send_magic_request(xpd->xbus, xpd->addr.unit, portno,
addr_mode == 'm');
goto out;
}
/* Normal (non-Magic) register commands */
do_datah = 0;
if (argno >= argc) {
if(argno >= argc) {
XPD_ERR(xpd, "Missing register number\n");
goto out;
}
regnum = parse_hexbyte(argv[argno]);
if (regnum < 0) {
if(regnum < 0) {
XPD_ERR(xpd, "Illegal register number '%s'\n", argv[argno]);
goto out;
}
//XPD_DBG(REGS, xpd, "Register is %X\n", regnum);
argno++;
if (do_subreg) {
if (argno >= argc) {
if(do_subreg) {
if(argno >= argc) {
XPD_ERR(xpd, "Missing subregister number\n");
goto out;
}
subreg = parse_hexbyte(argv[argno]);
if (subreg < 0) {
XPD_ERR(xpd, "Illegal subregister number '%s'\n",
argv[argno]);
if(subreg < 0) {
XPD_ERR(xpd, "Illegal subregister number '%s'\n", argv[argno]);
goto out;
}
//XPD_DBG(REGS, xpd, "Subreg is %X\n", subreg);
argno++;
} else
subreg = 0;
if (writing) {
if (argno >= argc) {
if(writing) {
if(argno >= argc) {
XPD_ERR(xpd, "Missing data low number\n");
goto out;
}
data_low = parse_hexbyte(argv[argno]);
if (data_low < 0) {
XPD_ERR(xpd, "Illegal data_low number '%s'\n",
argv[argno]);
if(data_low < 0) {
XPD_ERR(xpd, "Illegal data_low number '%s'\n", argv[argno]);
goto out;
}
//XPD_DBG(REGS, xpd, "Data Low is %X\n", data_low);
argno++;
} else
data_low = 0;
if (argno < argc) {
if(argno < argc) {
do_datah = 1;
if (!argv[argno]) {
if(!argv[argno]) {
XPD_ERR(xpd, "Missing data high number\n");
goto out;
}
data_high = parse_hexbyte(argv[argno]);
if (data_high < 0) {
XPD_ERR(xpd, "Illegal data_high number '%s'\n",
argv[argno]);
if(data_high < 0) {
XPD_ERR(xpd, "Illegal data_high number '%s'\n", argv[argno]);
goto out;
}
//XPD_DBG(REGS, xpd, "Data High is %X\n", data_high);
argno++;
} else
data_high = 0;
if (argno < argc) {
XPD_ERR(xpd, "Command contains an extra %d argument\n",
argc - argno);
if(argno < argc) {
XPD_ERR(xpd,
"Command contains an extra %d argument\n",
argc - argno);
goto out;
}
#if 0
XPD_DBG(REGS, xpd,
"portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d "
"dataL=%d do_datah=%d dataH=%d\n",
portno, /* portno */
writing, /* writing */
regnum, do_subreg, /* use subreg */
subreg, /* subreg */
data_low, do_datah, /* use data_high */
data_high);
"portno=%d writing=%d regnum=%d do_subreg=%d subreg=%d dataL=%d do_datah=%d dataH=%d\n",
portno, /* portno */
writing, /* writing */
regnum,
do_subreg, /* use subreg */
subreg, /* subreg */
data_low,
do_datah, /* use data_high*/
data_high);
#endif
ret = xpp_register_request(xpd->xbus, xpd, portno,
writing, regnum, do_subreg, subreg,
@@ -279,38 +271,36 @@ out:
return ret;
}
#define MAX_ARGS 10
int parse_chip_command(xpd_t *xpd, char *cmdline)
{
xbus_t *xbus;
int ret = -EBADR;
__u8 buf[MAX_PROC_WRITE];
char *str;
char *p;
char *argv[MAX_ARGS + 1];
int argc;
int i;
xbus_t *xbus;
int ret = -EBADR;
byte buf[MAX_PROC_WRITE];
char *str;
char *p;
static const int MAX_ARGS = 10;
char *argv[MAX_ARGS + 1];
int argc;
int i;
BUG_ON(!xpd);
xbus = xpd->xbus;
if (!XBUS_FLAGS(xbus, CONNECTED)) {
if(!XBUS_FLAGS(xbus, CONNECTED)) {
XBUS_DBG(GENERAL, xbus, "Dropped packet. Disconnected.\n");
return -EBUSY;
}
strlcpy(buf, cmdline, MAX_PROC_WRITE); /* Save a copy */
if (buf[0] == '#' || buf[0] == ';')
if(buf[0] == '#' || buf[0] == ';')
XPD_DBG(REGS, xpd, "Note: '%s'\n", buf);
if ((p = strchr(buf, '#')) != NULL) /* Truncate comments */
if((p = strchr(buf, '#')) != NULL) /* Truncate comments */
*p = '\0';
if ((p = strchr(buf, ';')) != NULL) /* Truncate comments */
if((p = strchr(buf, ';')) != NULL) /* Truncate comments */
*p = '\0';
/* Trim leading whitespace */
for (p = buf; *p && (*p == ' ' || *p == '\t'); p++)
for(p = buf; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */
;
str = p;
for (i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS;) {
if (*p != '\0') {
for(i = 0; (p = strsep(&str, " \t")) != NULL && i < MAX_ARGS; ) {
if(*p != '\0') {
argv[i] = p;
// XPD_DBG(REGS, xpd, "ARG %d = '%s'\n", i, p);
i++;
@@ -318,12 +308,11 @@ int parse_chip_command(xpd_t *xpd, char *cmdline)
}
argv[i] = NULL;
argc = i;
if (p) {
XPD_ERR(xpd, "Too many words (%d) to process. Last was '%s'\n",
i, p);
if(p) {
XPD_ERR(xpd, "Too many words (%d) to process. Last was '%s'\n", i, p);
goto out;
}
if (argc)
if(argc)
ret = execute_chip_command(xpd, argc, argv);
else
ret = 0; /* empty command - no op */
@@ -340,11 +329,11 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
/* 0x07 */ HOSTCMD(GLOBAL, AB_REQUEST)
{
int ret = -ENODEV;
xframe_t *xframe;
xpacket_t *pack;
int ret = -ENODEV;
xframe_t *xframe;
xpacket_t *pack;
if (!xbus) {
if(!xbus) {
DBG(DEVICES, "NO XBUS\n");
return -EINVAL;
}
@@ -354,35 +343,33 @@ static void global_packet_dump(const char *msg, xpacket_t *pack);
RPACKET_FIELD(pack, GLOBAL, AB_REQUEST, rev) = XPP_PROTOCOL_VERSION;
RPACKET_FIELD(pack, GLOBAL, AB_REQUEST, reserved) = 0;
XBUS_DBG(DEVICES, xbus, "Protocol Version %d\n", XPP_PROTOCOL_VERSION);
if (xbus_setstate(xbus, XBUS_STATE_SENT_REQUEST))
if(xbus_setstate(xbus, XBUS_STATE_SENT_REQUEST))
ret = send_cmd_frame(xbus, xframe);
return ret;
}
int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
bool writing, __u8 regnum, bool do_subreg, __u8 subreg,
__u8 data_low, bool do_datah, __u8 data_high,
bool should_reply)
bool writing, byte regnum, bool do_subreg, byte subreg,
byte data_low, bool do_datah, byte data_high, bool should_reply)
{
int ret = 0;
xframe_t *xframe;
xpacket_t *pack;
reg_cmd_t *reg_cmd;
int ret = 0;
xframe_t *xframe;
xpacket_t *pack;
reg_cmd_t *reg_cmd;
if (!xbus) {
if(!xbus) {
DBG(REGS, "NO XBUS\n");
return -EINVAL;
}
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST,
xpd->xbus_idx);
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, REGISTER_REQUEST, xpd->xbus_idx);
LINE_DBG(REGS, xpd, portno, "%c%c %02X %02X %02X %02X\n",
(writing) ? 'W' : 'R', (do_subreg) ? 'S' : 'D', regnum, subreg,
data_low, data_high);
(writing)?'W':'R',
(do_subreg)?'S':'D',
regnum, subreg, data_low, data_high);
reg_cmd = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REQUEST, reg_cmd);
/* do not count the 'bytes' field */
reg_cmd->bytes = sizeof(*reg_cmd) - 1;
reg_cmd->bytes = sizeof(*reg_cmd) - 1; // do not count the 'bytes' field
reg_cmd->is_multibyte = 0;
if (portno == PORT_BROADCAST) {
if(portno == PORT_BROADCAST) {
reg_cmd->portnum = 0;
REG_FIELD(reg_cmd, all_ports_broadcast) = 1;
} else {
@@ -398,15 +385,14 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
REG_FIELD(reg_cmd, do_datah) = do_datah;
REG_FIELD(reg_cmd, data_low) = data_low;
REG_FIELD(reg_cmd, data_high) = data_high;
if (should_reply)
if(should_reply)
xpd->requested_reply = *reg_cmd;
if (debug & DBG_REGS) {
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit,
reg_cmd->portnum, reg_cmd);
if(debug & DBG_REGS) {
dump_reg_cmd("REG_REQ", 1, xbus, xpd->addr.unit, reg_cmd->portnum, reg_cmd);
dump_packet("REG_REQ", pack, 1);
}
if (!xframe->usec_towait) { /* default processing time of SPI */
if (subreg)
if(!xframe->usec_towait) { /* default processing time of SPI */
if(subreg)
xframe->usec_towait = 2000;
else
xframe->usec_towait = 1000;
@@ -414,19 +400,18 @@ int xpp_register_request(xbus_t *xbus, xpd_t *xpd, xportno_t portno,
ret = send_cmd_frame(xbus, xframe);
return ret;
}
EXPORT_SYMBOL(xpp_register_request);
/*
* The XPD parameter is totaly ignored by the driver and firmware as well.
*/
/* 0x19 */ HOSTCMD(GLOBAL, SYNC_SOURCE, enum sync_mode mode, int drift)
{
xframe_t *xframe;
xpacket_t *pack;
const char *mode_name;
xframe_t *xframe;
xpacket_t *pack;
const char *mode_name;
BUG_ON(!xbus);
if ((mode_name = sync_mode_name(mode)) == NULL) {
if((mode_name = sync_mode_name(mode)) == NULL) {
XBUS_ERR(xbus, "SYNC_SOURCE: bad sync_mode=0x%X\n", mode);
return -EINVAL;
}
@@ -443,8 +428,8 @@ EXPORT_SYMBOL(xpp_register_request);
*/
static int send_xbus_reset(xbus_t *xbus, uint8_t reset_mask)
{
xframe_t *xframe;
xpacket_t *pack;
xframe_t *xframe;
xpacket_t *pack;
BUG_ON(!xbus);
XFRAME_NEW_CMD(xframe, pack, xbus, GLOBAL, XBUS_RESET, 0);
@@ -477,14 +462,14 @@ HANDLER_DEF(GLOBAL, NULL_REPLY)
return 0;
}
HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
{ /* 0x08 */
struct xbus_workqueue *worker;
__u8 rev;
struct unit_descriptor *units;
int count_units;
int i;
int ret = 0;
HANDLER_DEF(GLOBAL, AB_DESCRIPTION) /* 0x08 */
{
struct xbus_workqueue *worker;
byte rev;
struct unit_descriptor *units;
int count_units;
int i;
int ret = 0;
if (!xbus) {
NOTICE("%s: xbus is gone!!!\n", __func__);
@@ -492,36 +477,31 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
}
rev = RPACKET_FIELD(pack, GLOBAL, AB_DESCRIPTION, rev);
units = RPACKET_FIELD(pack, GLOBAL, AB_DESCRIPTION, unit_descriptor);
count_units = XPACKET_LEN(pack) - ((__u8 *)units - (__u8 *)pack);
count_units = XPACKET_LEN(pack) - ((byte *)units - (byte *)pack);
count_units /= sizeof(*units);
if (rev != XPP_PROTOCOL_VERSION) {
if(rev != XPP_PROTOCOL_VERSION) {
XBUS_NOTICE(xbus, "Bad protocol version %d (should be %d)\n",
rev, XPP_PROTOCOL_VERSION);
rev, XPP_PROTOCOL_VERSION);
ret = -EPROTO;
goto proto_err;
}
if (count_units > NUM_UNITS) {
if(count_units > NUM_UNITS) {
XBUS_NOTICE(xbus, "Too many units %d (should be %d)\n",
count_units, NUM_UNITS);
count_units, NUM_UNITS);
ret = -EPROTO;
goto proto_err;
}
if (count_units <= 0) {
XBUS_NOTICE(xbus, "Empty astribank? (%d units)\n", count_units);
if(count_units <= 0) {
XBUS_NOTICE(xbus, "Empty astribank? (%d units)\n",
count_units);
ret = -EPROTO;
goto proto_err;
}
if (units[0].addr.unit != 0 || units[0].addr.subunit != 0) {
XBUS_NOTICE(xbus, "No first module. Astribank unusable.\n");
if(!xbus_setstate(xbus, XBUS_STATE_RECVD_DESC)) {
ret = -EPROTO;
goto proto_err;
}
if (!xbus_setstate(xbus, XBUS_STATE_RECVD_DESC)) {
ret = -EPROTO;
goto proto_err;
}
XBUS_INFO(xbus, "DESCRIPTOR: %d cards, protocol revision %d\n",
count_units, rev);
XBUS_INFO(xbus, "DESCRIPTOR: %d cards, protocol revision %d\n", count_units, rev);
if (xbus_check_unique(xbus))
return -EBUSY;
xbus->revision = rev;
@@ -531,14 +511,12 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
ret = -ENODEV;
goto out;
}
for (i = 0; i < count_units; i++) {
struct unit_descriptor *this_unit = &units[i];
struct card_desc_struct *card_desc;
unsigned long flags;
for(i = 0; i < count_units; i++) {
struct unit_descriptor *this_unit = &units[i];
struct card_desc_struct *card_desc;
unsigned long flags;
if ((card_desc =
KZALLOC(sizeof(struct card_desc_struct),
GFP_ATOMIC)) == NULL) {
if((card_desc = KZALLOC(sizeof(struct card_desc_struct), GFP_ATOMIC)) == NULL) {
XBUS_ERR(xbus, "Card description allocation failed.\n");
ret = -ENOMEM;
goto out;
@@ -551,15 +529,16 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
card_desc->numchips = this_unit->numchips;
card_desc->ports_per_chip = this_unit->ports_per_chip;
card_desc->port_dir = this_unit->port_dir;
card_desc->ports =
card_desc->numchips * card_desc->ports_per_chip;
XBUS_INFO(xbus,
" CARD %d type=%d.%d ports=%d (%dx%d), "
"port-dir=0x%02X\n",
card_desc->xpd_addr.unit, card_desc->type,
card_desc->subtype, card_desc->ports,
card_desc->numchips, card_desc->ports_per_chip,
card_desc->port_dir);
card_desc->ports = card_desc->numchips * card_desc->ports_per_chip;
XBUS_INFO(xbus, " CARD %d type=%d.%d ports=%d (%dx%d), port-dir=0x%02X\n",
card_desc->xpd_addr.unit,
card_desc->type,
card_desc->subtype,
card_desc->ports,
card_desc->numchips,
card_desc->ports_per_chip,
card_desc->port_dir
);
spin_lock_irqsave(&worker->worker_lock, flags);
worker->num_units++;
XBUS_COUNTER(xbus, UNITS)++;
@@ -573,7 +552,6 @@ HANDLER_DEF(GLOBAL, AB_DESCRIPTION)
}
goto out;
proto_err:
xbus_setstate(xbus, XBUS_STATE_FAIL);
dump_packet("AB_DESCRIPTION", pack, DBG_ANY);
out:
return ret;
@@ -581,23 +559,21 @@ out:
HANDLER_DEF(GLOBAL, REGISTER_REPLY)
{
reg_cmd_t *reg = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REPLY, regcmd);
reg_cmd_t *reg = &RPACKET_FIELD(pack, GLOBAL, REGISTER_REPLY, regcmd);
if (!xpd) {
static int rate_limit;
if(!xpd) {
static int rate_limit;
if ((rate_limit++ % 1003) < 5)
notify_bad_xpd(__func__, xbus, XPACKET_ADDR(pack), "");
if((rate_limit++ % 1003) < 5)
notify_bad_xpd(__FUNCTION__, xbus, XPACKET_ADDR(pack), "");
return -EPROTO;
}
if (debug & DBG_REGS) {
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->portnum,
reg);
if(debug & DBG_REGS) {
dump_reg_cmd("REG_REPLY", 0, xbus, xpd->addr.unit, reg->portnum, reg);
dump_packet("REG_REPLY", pack, 1);
}
if (!XMETHOD(card_register_reply, xpd)) {
XPD_ERR(xpd,
"REGISTER_REPLY: missing card_register_reply()\n");
if (! XMETHOD(card_register_reply, xpd)) {
XPD_ERR(xpd, "REGISTER_REPLY: without card_register_reply() method\n");
return -EINVAL;
}
return CALL_XMETHOD(card_register_reply, xpd, reg);
@@ -605,12 +581,12 @@ HANDLER_DEF(GLOBAL, REGISTER_REPLY)
HANDLER_DEF(GLOBAL, SYNC_REPLY)
{
__u8 mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
__u8 drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
const char *mode_name;
byte mode = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, sync_mode);
byte drift = RPACKET_FIELD(pack, GLOBAL, SYNC_REPLY, drift);
const char *mode_name;
BUG_ON(!xbus);
if ((mode_name = sync_mode_name(mode)) == NULL) {
if((mode_name = sync_mode_name(mode)) == NULL) {
XBUS_ERR(xbus, "SYNC_REPLY: bad sync_mode=0x%X\n", mode);
return -EINVAL;
}
@@ -624,26 +600,24 @@ HANDLER_DEF(GLOBAL, SYNC_REPLY)
HANDLER_DEF(GLOBAL, ERROR_CODE)
{
char tmp_name[TMP_NAME_LEN];
static long rate_limit;
__u8 category_code;
__u8 errorbits;
char tmp_name[TMP_NAME_LEN];
static long rate_limit;
byte category_code;
byte errorbits;
BUG_ON(!xbus);
if ((rate_limit++ % 5003) > 200)
if((rate_limit++ % 5003) > 200)
return 0;
category_code = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, category_code);
errorbits = RPACKET_FIELD(pack, GLOBAL, ERROR_CODE, errorbits);
if (!xpd) {
if(!xpd) {
snprintf(tmp_name, TMP_NAME_LEN, "%s(%1d%1d)", xbus->busname,
XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
XPACKET_ADDR_UNIT(pack), XPACKET_ADDR_SUBUNIT(pack));
} else {
snprintf(tmp_name, TMP_NAME_LEN, "%s/%s", xbus->busname,
xpd->xpdname);
snprintf(tmp_name, TMP_NAME_LEN, "%s/%s", xbus->busname, xpd->xpdname);
}
NOTICE
("%s: FIRMWARE %s: category=%d errorbits=0x%02X (rate_limit=%ld)\n",
tmp_name, cmd->name, category_code, errorbits, rate_limit);
NOTICE("%s: FIRMWARE %s: category=%d errorbits=0x%02X (rate_limit=%ld)\n",
tmp_name, cmd->name, category_code, errorbits, rate_limit);
dump_packet("FIRMWARE: ", pack, 1);
/*
* FIXME: Should implement an error recovery plan
@@ -651,14 +625,15 @@ HANDLER_DEF(GLOBAL, ERROR_CODE)
return 0;
}
xproto_table_t PROTO_TABLE(GLOBAL) = {
.entries = {
/* Prototable Card Opcode */
XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
XENTRY( GLOBAL, GLOBAL, AB_DESCRIPTION ),
XENTRY( GLOBAL, GLOBAL, NULL_REPLY ),
XENTRY( GLOBAL, GLOBAL, AB_DESCRIPTION ),
XENTRY( GLOBAL, GLOBAL, SYNC_REPLY ),
XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
XENTRY( GLOBAL, GLOBAL, REGISTER_REPLY ),
XENTRY( GLOBAL, GLOBAL, ERROR_CODE ),
XENTRY( GLOBAL, GLOBAL, REGISTER_REPLY ),
},
.name = "GLOBAL",
.packet_is_valid = global_packet_is_valid,
@@ -667,7 +642,7 @@ xproto_table_t PROTO_TABLE(GLOBAL) = {
static bool global_packet_is_valid(xpacket_t *pack)
{
const xproto_entry_t *xe;
const xproto_entry_t *xe;
//DBG(GENERAL, "\n");
xe = xproto_global_entry(XPACKET_OP(pack));
@@ -692,26 +667,26 @@ static void global_packet_dump(const char *msg, xpacket_t *pack)
int run_initialize_registers(xpd_t *xpd)
{
int ret;
xbus_t *xbus;
char busstr[MAX_ENV_STR];
char busnumstr[MAX_ENV_STR];
char modelstr[MAX_ENV_STR];
char unitstr[MAX_ENV_STR];
char subunitsstr[MAX_ENV_STR];
char typestr[MAX_ENV_STR];
char directionstr[MAX_ENV_STR];
char revstr[MAX_ENV_STR];
char connectorstr[MAX_ENV_STR];
char xbuslabel[MAX_ENV_STR];
char init_card[MAX_PATH_STR];
__u8 direction_mask;
int i;
char *argv[] = {
int ret;
xbus_t *xbus;
char busstr[MAX_ENV_STR];
char busnumstr[MAX_ENV_STR];
char modelstr[MAX_ENV_STR];
char unitstr[MAX_ENV_STR];
char subunitsstr[MAX_ENV_STR];
char typestr[MAX_ENV_STR];
char directionstr[MAX_ENV_STR];
char revstr[MAX_ENV_STR];
char connectorstr[MAX_ENV_STR];
char xbuslabel[MAX_ENV_STR];
char init_card[MAX_PATH_STR];
byte direction_mask;
int i;
char *argv[] = {
init_card,
NULL
};
char *envp[] = {
char *envp[] = {
busstr,
busnumstr,
modelstr,
@@ -727,82 +702,74 @@ int run_initialize_registers(xpd_t *xpd)
BUG_ON(!xpd);
xbus = xpd->xbus;
if (!initdir || !initdir[0]) {
if(!initdir || !initdir[0]) {
XPD_NOTICE(xpd, "Missing initdir parameter\n");
ret = -EINVAL;
goto err;
}
if (!xpd_setstate(xpd, XPD_STATE_INIT_REGS)) {
if(!xpd_setstate(xpd, XPD_STATE_INIT_REGS)) {
ret = -EINVAL;
goto err;
}
direction_mask = 0;
for (i = 0; i < xpd->subunits; i++) {
xpd_t *su = xpd_byaddr(xbus, xpd->addr.unit, i);
for(i = 0; i < xpd->subunits; i++) {
xpd_t *su = xpd_byaddr(xbus, xpd->addr.unit, i);
if (!su) {
XPD_ERR(xpd, "Have %d subunits, but not subunit #%d\n",
if(!su) {
XPD_ERR(xpd,
"Have %d subunits, but not subunit #%d\n",
xpd->subunits, i);
continue;
}
direction_mask |=
(PHONEDEV(su).direction == TO_PHONE) ? BIT(i) : 0;
direction_mask |= (PHONEDEV(su).direction == TO_PHONE) ? BIT(i) : 0;
}
snprintf(busstr, MAX_ENV_STR, "XBUS_NAME=%s", xbus->busname);
snprintf(busnumstr, MAX_ENV_STR, "XBUS_NUMBER=%d", xbus->num);
snprintf(modelstr, MAX_ENV_STR, "XBUS_MODEL_STRING=%s",
xbus->transport.model_string);
snprintf(modelstr, MAX_ENV_STR, "XBUS_MODEL_STRING=%s", xbus->transport.model_string);
snprintf(unitstr, MAX_ENV_STR, "UNIT_NUMBER=%d", xpd->addr.unit);
snprintf(typestr, MAX_ENV_STR, "UNIT_TYPE=%d", xpd->type);
snprintf(subunitsstr, MAX_ENV_STR, "UNIT_SUBUNITS=%d", xpd->subunits);
snprintf(directionstr, MAX_ENV_STR, "UNIT_SUBUNITS_DIR=%d",
direction_mask);
snprintf(directionstr, MAX_ENV_STR, "UNIT_SUBUNITS_DIR=%d", direction_mask);
snprintf(revstr, MAX_ENV_STR, "XBUS_REVISION=%d", xbus->revision);
snprintf(connectorstr, MAX_ENV_STR, "XBUS_CONNECTOR=%s",
xbus->connector);
snprintf(connectorstr, MAX_ENV_STR, "XBUS_CONNECTOR=%s", xbus->connector);
snprintf(xbuslabel, MAX_ENV_STR, "XBUS_LABEL=%s", xbus->label);
if (snprintf
(init_card, MAX_PATH_STR, "%s/init_card_%d_%d", initdir, xpd->type,
xbus->revision) > MAX_PATH_STR) {
XPD_NOTICE(xpd,
"Cannot initialize. pathname is longer "
"than %d characters.\n",
MAX_PATH_STR);
if(snprintf(init_card, MAX_PATH_STR, "%s/init_card_%d_%d",
initdir, xpd->type, xbus->revision) > MAX_PATH_STR) {
XPD_NOTICE(xpd, "Cannot initialize. pathname is longer than %d characters.\n", MAX_PATH_STR);
ret = -E2BIG;
goto err;
}
if (!XBUS_IS(xbus, RECVD_DESC)) {
XBUS_ERR(xbus,
"Skipped register initialization. In state %s.\n",
xbus_statename(XBUS_STATE(xbus)));
if(!XBUS_IS(xbus, RECVD_DESC)) {
XBUS_ERR(xbus, "Skipped register initialization. In state %s.\n",
xbus_statename(XBUS_STATE(xbus)));
ret = -ENODEV;
goto err;
}
XPD_DBG(DEVICES, xpd, "running '%s' for type=%d revision=%d\n",
init_card, xpd->type, xbus->revision);
init_card, xpd->type, xbus->revision);
ret = call_usermodehelper(init_card, argv, envp, UMH_WAIT_PROC);
/*
* Carefully report results
*/
if (ret == 0)
if(ret == 0)
XPD_DBG(DEVICES, xpd, "'%s' finished OK\n", init_card);
else if (ret < 0) {
XPD_ERR(xpd, "Failed running '%s' (errno %d)\n", init_card,
ret);
else if(ret < 0) {
XPD_ERR(xpd, "Failed running '%s' (errno %d)\n", init_card, ret);
} else {
__u8 exitval = ((unsigned)ret >> 8) & 0xFF;
__u8 sigval = ret & 0xFF;
byte exitval = ((unsigned)ret >> 8) & 0xFF;
byte sigval = ret & 0xFF;
if (!exitval) {
XPD_ERR(xpd, "'%s' killed by signal %d\n", init_card,
sigval);
if(!exitval) {
XPD_ERR(xpd, "'%s' killed by signal %d\n", init_card, sigval);
} else {
XPD_ERR(xpd, "'%s' aborted with exitval %d\n",
init_card, exitval);
XPD_ERR(xpd, "'%s' aborted with exitval %d\n", init_card, exitval);
}
ret = -EINVAL;
}
err:
return ret;
}
EXPORT_SYMBOL(sync_mode_name);
EXPORT_SYMBOL(run_initialize_registers);
EXPORT_SYMBOL(xpp_register_request);

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
USB_FW = USB_FW.hex USB_FW.201.hex USB_RECOV.hex
FPGA_FW = FPGA_FXS.hex FPGA_1141.hex FPGA_1151.hex FPGA_1161.hex \
FPGA_1161.201.hex FPGA_1161.202.hex
FPGA_1161.201.hex
PIC_FW = PIC_TYPE_1.hex PIC_TYPE_2.hex PIC_TYPE_3.hex PIC_TYPE_4.hex
OCT_FW = $(wildcard OCT6104E-256D.ima)
FIRMWARES = $(USB_FW) $(FPGA_FW) $(PIC_FW) $(OCT_FW)
@@ -20,7 +20,4 @@ install:
mkdir -p $(TARGET)
install $(SCRIPTS) $(TARGET)/
install -m 644 ../XppConfig.pm $(FIRMWARES) $(TARGET)/
if [ ! -r $(TARGET)/USB_FW.202.hex ]; then \
ln -s USB_FW.201.hex $(TARGET)/USB_FW.202.hex;\
fi

View File

@@ -1,7 +1,7 @@
#
# $Id: PIC_TYPE_2.hex 11078 2013-04-11 16:52:37Z dima $
# $Id: PIC_TYPE_2.hex 9732 2011-08-24 19:13:55Z dima $
#
:03000000A5DA4836
:03000000A57A4896
:03000100C41C41DB
:030002000390392F
:0300030067967984
@@ -42,375 +42,319 @@
:03002600CFC9013E
:030027001652026C
:0300280064403001
:03002900A38901A7
:03002900A3290107
:03002A00704C40D7
:03002B00A47FFFB0
:03002C00C40165A7
:03002D00150C02AD
:03002E00743FFF1D
:03002F00A32150BA
:03003000C026B92E
:03003100A33D02EA
:03003200C01022D9
:03003300121C029A
:03003400C03D01CB
:030035001611623F
:0300360020120590
:0300370012503034
:0300380020A901FB
:030039006432042A
:03003A00A40030EF
:03003B0036590132
:03003C0036520237
:03003D002C8030E4
:03003E00D00901E5
:03003F00A3980083
:0300400020521437
:03004100724E708C
:03004200A44308CC
:03004300A46308AB
:0300440002D308DC
:03004500A4730899
:0300460002E03F96
:030047008008002E
:03004800022C0087
:03004900206039FB
:03004A00643038E7
:03004B00A50C07FA
:03004C00322D4012
:03004D002C8034D0
:03004E00D00C08CB
:03004F00A4A03832
:03005000CFE219E3
:03005100162E0761
:03005200C01020BB
:03005300604360A7
:0300540012236014
:03005500206360C5
:03005600643360B0
:03005700A5CC1025
:0300580036203817
:030059002C8219DD
:03005A00D00E07BE
:03005B00A561207C
:03005C00800C20F5
:03005D00C07180EF
:03005E00166E70AB
:03005F00743743B0
:03006000A65A702D
:03006100C01C02BE
:030062001CC1803E
:03006300E07E0735
:0300640002C6438E
:03006500200A73FB
:03002B00A41FFF10
:03002C00C011659B
:03002D001E1C0294
:03002E00C03FFFD1
:03002F0016115057
:030030002016B9DE
:03003100125D025B
:0300320020A022E9
:03003300643C0228
:03003400A3AD0178
:03003500365162DF
:030036003652053A
:030037002C8030EA
:03003800D00901EB
:03003900A33204EB
:03003A0020503023
:03003B0072490106
:03003C00A3E2023A
:03003D00A40030EC
:03003E0002D901E3
:03003F00A4180002
:0300400002E214C5
:03004100800E70BE
:030042000223088E
:030043002063082F
:030044006433081A
:03004500A4A30869
:0300460032203F26
:030047002C880002
:03004800D00C00D9
:03004900A4403997
:03004A00CFE038CC
:03004B00162C0769
:03004C00C01D4094
:03004D00604034DC
:03004E00122C0869
:03004F00206038F6
:03005000643219FE
:03005100A56E0792
:0300520036202035
:030053002C83609B
:03005400D0036076
:03005500A50360A0
:03005600800360C4
:03005700C07C105A
:03005800166038F7
:03005900743219E5
:03005A00A5FE07F9
:03005B00C01120B1
:03005C001CCC2099
:03005D00E07180CF
:03005E0002CE705F
:03005F00206743D4
:0300600090AA70F3
:03006100205C021E
:03006200D2018048
:03006300D40E07B1
:0300640003D6437D
:03006500C1CA739A
:03006600022C0366
:0300670020618095
:03006800643E07EC
:03006900A6E643C5
:03006A00322A73C4
:03006B002C8C04D6
:03006C00D0018040
:03006D00A68E0755
:03006E00C0164376
:03006F00142A73DD
:03007000743C01DC
:03007100ACB038F8
:03007200206A728F
:0300730090AC1836
:03007400205038E1
:03007500D202199B
:03007600D40E0F96
:0300770003D02291
:03007800C04C0079
:030079000220382A
:03006700C0018055
:03006800024E073E
:0300690021D6435A
:03006A00030A7313
:03006B00901C04E2
:03006C00202180D0
:03006D00030E0778
:03006E00901643A6
:03006F00204A73B1
:03007000030C017D
:03007100901038B4
:03007200210A72EE
:03007300024C1824
:03007400C0303861
:0300750008421925
:03007600603E0FDA
:03007700A7A0221D
:03007800209C00C9
:03007900A7C038E5
:03007A00C00200C1
:03007B00024E072B
:03007C0021DF027F
:03007D0003074333
:03007E00901A8352
:03007F00202C0032
:0300800003003149
:03008100901C12BE
:03008200204A9081
:0300830003020075
:03008400901E07C4
:03008500210F0345
:03008600E017433D
:03008700643A8C4C
:03008800ACBC000D
:0300890021003122
:03008A00024C180D
:03008B00E80A90F0
:03008C00743C00C1
:03008D00AB803114
:03008E00C50C1688
:03008F00039A9041
:0300900079903B29
:03009100A90E0FA6
:0300920020B08219
:03009300D0070390
:03009400038A9A42
:03009500219C0F9C
:03009600E07FFF09
:0300970034815B56
:03009800348102AE
:03009900348A9B0B
:03009A0034821B92
:03009B000300302F
:03009C00206E0FC4
:03009D0034803B71
:03009E00348C029D
:03009F0034803971
:0300A000348C009D
:0300A100D0503903
:0300A200031C80BC
:03007B00A7CE0706
:03007C00187F02E8
:03007D0014974392
:03007E00643A835E
:03007F00AABC0018
:030080001A7031C2
:03008100C50C1299
:03008200039A904E
:030083007992006F
:03008400A83E078C
:0300850020BF0396
:03008600D007435D
:03008700038A8C5D
:03008800219C00B8
:03008900E07031F3
:03008A00348C189B
:03008B00348A9024
:03008C00348C00B1
:03008D003480318B
:03008E00030C164A
:03008F00206A9054
:0300900034803B7E
:03009100348E0F9B
:0300920034808235
:03009300348703AC
:03009400D05A9AA5
:03009500031C0F3A
:03009600C00FFF99
:0300970003215BE7
:030098000331022F
:03009900C70A9BF8
:03009A0003921BB3
:03009B00C500306D
:03009C00039E0FB1
:03009D00C1C03BA4
:03009E00030C024E
:03009F00C0003965
:0300A000031C003E
:0300A100204039C3
:0300A200032C80AC
:0300A300C00D0885
:0300A400032039FD
:0300A500033C0019
:0300A600C7003957
:0300A700039C4077
:0300A800C5003957
:0300A9000397D9E1
:0300AA00C04AA9A0
:0300AB00030C0043
:0300AC00C000266B
:0300AD0003102716
:0300AE0020402BC4
:0300AF000320200B
:0300B000C00C037E
:0300B10003302CED
:0300B200C70C2058
:0300B300039D802A
:0300B400C500255F
:0300B500039C2089
:0300B600C400245F
:0300B700039C00A7
:0300B800C400225F
:0300B900FFF2054E
:0300BA00165030AD
:0300BB00D2090166
:0300BC0003D20468
:0300BD00C0403010
:0300BE0002290113
:0300BF00C002027A
:0300A400033039ED
:0300A500C70C0085
:0300A6000390398B
:0300A700C50C4045
:0300A80003903989
:0300A900C407D9B0
:0300AA00039AA90D
:0300AB0020CC0066
:0300AC0074302687
:0300AD00B1702708
:0300AE00C0002B64
:0300AF00024020EC
:0300B000C05C032E
:0300B10002202CFE
:0300B200205C20AF
:0300B300D20D80EB
:0300B400D4002550
:0300B50003DC2049
:0300B60021D02432
:0300B700030C0037
:0300B80090102283
:0300B900202205FD
:0300BA0003003010
:0300BB0090190198
:0300BC00204204DB
:0300BD000300300D
:0300BE0090190195
:0300BF00C012026A
:0300C000150030F8
:0300C100024901F0
:0300C20021DC40FE
:0300C300030039FE
:0300C400901C018C
:0300C500202037C1
:0300C600030C60C8
:0300C7009012C8CC
:0300C800204AC704
:0300C900030C0025
:0300CA009010375C
:0300CB002066D9D3
:0300CC0090AAD027
:0300CD002056F9C1
:0300CE00D20B4D05
:0300C20021AC402E
:0300C3009420394D
:0300C400202C01EC
:0300C50003A0375E
:0300C600206C604B
:0300C7007432C8C8
:0300C800AD5AC767
:0300C900C9FC006F
:0300CA0016B03736
:0300CB00C006D993
:0300CC006B0AD0EC
:0300CD00D206F95F
:0300CE006D0B4D6A
:0300CF00D40ACB85
:0300D00003D94011
:0300D100C1CC207F
:0300D20002219573
:0300D300C0064321
:0300D400024ADFFE
:0300D50021DC012A
:0300D6000301DF44
:0300D70090109BEB
:0300D800202703DB
:0300D900030ADF38
:0300DA009017D3A9
:0300DB00204B486F
:0300DC00030CFF13
:0300DD009010225E
:0300DE00210B2AC9
:0300DF0002421FBB
:0300E000C0390A1A
:0300E100084C20A8
:0300E20060312565
:0300E300AE66D333
:0300E400209AEA75
:0300E500AE8C20BE
:0300E600C00095C2
:0300E700AE86439F
:0300E800187AF291
:0300E900149AEF77
:0300EA00643C4033
:0300EB00B17125CB
:0300EC001A7C007B
:0300ED00C5002427
:0300EE00039B1A57
:0300EF00799217EC
:0300F000AEF0244B
:0300F10020BB1A17
:0300F200D00C40EF
:0300F30003810581
:0300F40021903D1B
:0300F500E07C00AC
:0300F6003480242F
:0300F70034821D33
:0300F80034803021
:0300F90034890146
:0300FA00030215E9
:0300FB0020603052
:0300FC0034890143
:0300FD0034820446
:0300FE003480301B
:0300FF0034890140
:03010000D05210CA
:03010100031024C4
:03010200C007F73C
:03010300032B0BC0
:03010400033C02B7
:03010500C70FFF22
:03010600039164FE
:03010700C50C0222
:0301080003915709
:03010900C1C1244D
:03010A00030B17CD
:03010B00C007D753
:03010C00031B17BB
:03010D00204C0182
:03010E00032FFFBD
:03010F00C00164C8
:03011000033C01AC
:03011100C70157CC
:0301120003912432
:03011300C50B1702
:030114000392173C
:03011500C40024FF
:03011600039B1731
:0301170020CC02F7
:03011800743D0132
:03011900B8316496
:03011A00C00C8096
:03011B000246F3A6
:03011C00C05125AA
:03011D00022205B6
:03011E002050303E
:03011F00D2090101
:03012000D40215F1
:0301210003D030D8
:0301220021D901DF
:03012300030204D0
:0301240090103008
:030125002029018D
:030126000307D3F9
:03012700901B48E2
:0301280020421062
:03012900030022AE
:03012A00901C50D6
:03012B00C01039C8
:03012C001507991B
:03012D00024B2C56
:03012E0021A212F9
:03012F0094803089
:0301300020221476
:0301310003A031F7
:0301320020621335
:03013300743032F3
:03013400B41C00F8
:03013500C9F033DB
:0301360016BC7084
:03013700C00039CC
:030138006B0C50FD
:03013900D20039B8
:03013A006D02153E
:03013B00D40030BD
:03013C0012BC00F2
:03013D00C80031C6
:03013E001AB202F0
:03013F0020B032BB
:03014000038C002D
:0301410020603308
:0301420002AC709C
:03014300C0403980
:03014400086C50F4
:03014500703039DE
:03014600B4AC4016
:03014700C00039BC
:03014800024C0066
:03014900B4E039E6
:03014A00C04C00A6
:03014B000AAC00FB
:03014C00C02AC204
:03014D00024C0061
:03014E0091702588
:03014F00C01C10C1
:0301500003E03D8C
:030151002069170B
:03015200643C0406
:03015300B570255F
:0301540037EC0085
:030155002C803DBE
:03015600B5491791
:03015700C60C02D1
:030158001500256A
:03015900743C08EB
:03015A00B6B03DFF
:03015B0021E91780
:03015C001AFC008A
:03015D0014F02675
:03015E00743C01ED
:03015F00B830298C
:03016000C04C2070
:0301610012402326
:03016200917A008F
:03016300C00B636B
:0301640002400056
:0301650020000077
:0301660094800082
:0301670020200055
:0301680002000092
:0301690003500040
:03016A00B83000AA
:03016B00CFF000D2
:03016C0019E00097
:03016D0016F00089
:03016E00C030009E
:03016F0008100075
:03017000743000E8
:03017100B7A00034
:03017200C01000BA
:0301730002400047
:0301740020000068
:0301750094800073
:0301760020200046
:0301770002000083
:0301780003500031
:03017900B830009B
:03017A00C00000C2
:03017B0018100059
:03017C00643000EC
:03017D006B000014
:03017E00B80000C6
:03017F00B8300095
:03018000C01000AC
:0301810012400029
:0301820091700079
:03018300369000B3
:03018400C01000A8
:030185001E6000F9
:0301860021B000A5
:030187000860000D
:03018800743000D0
:03018900A5D000FE
:03018A0002600010
:03018B00C0200091
:03018C00FFF00081
:03018D0016B000A9
:03018E00C020008E
:03018F0023A000AA
:03019000743000C8
:0301910012B000A9
:0301920020B0009A
:03019300038000E6
:03019400C4400064
:03019500039000D4
:03019600C40000A2
:03019700039000D2
:03019800C00000A4
:0301990002300031
:03019A00AC200096
:03019B00B9B000F8
:0300D00012B94022
:0300D100C80C2038
:0300D2001AB195CB
:0300D30020B64311
:0300D400038ADFBD
:0300D500206C019B
:0300D60002A1DFA5
:0300D700C0409B8B
:0300D800086703B3
:0300D900703ADF9B
:0300DA00ADE7D3BC
:0300DB00C00B480F
:0300DC00024CFFD4
:0300DD00AE202230
:0300DE00C04B2AEA
:0300DF000AA21F53
:0300E000C0290A2A
:0300E100024C20AE
:0300E200917125F4
:0300E300C016D371
:0300E40003EAEA42
:0300E500206C206C
:0300E600643095EE
:0300E700AEB6436F
:0300E80037EAF202
:0300E9002C8AEF6F
:0300EA00AE8C4099
:0300EB00C6012526
:0300EC00150C00F0
:0300ED0074302448
:0300EE00AFFB1A4B
:0300EF0021E217F4
:0300F0001AF024DF
:0300F10014FB1AE3
:0300F200743C401B
:0300F300B17105E3
:0300F400C0403DCC
:0300F500124C00AA
:0300F600917024E2
:0300F700C0021D27
:0300F80002403093
:0300F900200901DA
:0300FA0094221538
:0300FB0020203092
:0300FC00020901F5
:0300FD00035204A7
:0300FE00B17030AE
:0300FF00CFF90135
:0301000019E210F1
:0301010016F024D1
:03010200C037F70C
:03010300081B0BCB
:03010400743C0246
:03010500B0EFFF59
:03010600C01164C1
:03010700024C02A5
:030108002001577C
:030109009421241A
:03010A00202B1790
:03010B000207D711
:03010C00035B177B
:03010D00B17C01C1
:03010E00C00FFF20
:03010F0018116460
:03011000643C014B
:030111006B015728
:03011200B14124D4
:03011300B17B17A6
:03011400C01217FF
:0301150012402471
:03011600917B17C3
:03011700369C0211
:03011800C01D0106
:030119001E616400
:03011A0021BC8085
:03011B000866F380
:03011C0074312516
:03011D00A57205C3
:03011E000260304C
:03011F00C02901F3
:03012000FFF215D6
:0301210016B030E5
:03012200C02901F0
:0301230023A20410
:0301240074303004
:0301250012B9010B
:0301260020B7D32C
:03012700038B48FF
:03012800C44210BE
:030129000390221E
:03012A00C40C50B2
:03012B0003903905
:03012C00C0079970
:03012D00023B2C66
:03012E00AC2212EE
:03012F00B2F030FB
:03013000000214B6
:030131000000319A
:03013200000213B5
:0301330000003297
:03013400000C00BC
:0301350000003394
:03013600000C704A
:030137000000398C
:03013800000C5068
:030139000000398A
:03013A00000215AB
:03013B0000003091
:03013C00000C00B4
:03013D000000318E
:03013E00000202BA
:03013F000000328B
:03014000000C00B0
:0301410000003388
:03014200000C703E
:0301430000003980
:03014400000C505C
:030145000000397E
:03014600000C406A
:030147000000397C
:03014800000C00A8
:030149000000397A
:03014A00000C00A6
:03014B00000C00A5
:03014C00000AC2E4
:03014D00000C00A3
:03014E0000002589
:03014F00000C1091
:0301500000003D6F
:030151000009178B
:03015200000C049A
:0301530000002584
:03015400000C009C
:0301550000003D6A
:0301560000091786
:03015700000C0297
:030158000000257F
:03015900000C088F
:03015A0000003D65
:03015B0000091781
:03015C00000C0094
:03015D0000002679
:03015E00000C0191
:03015F0000002974
:03016000000C2070
:0301610000002378
:03016200000A0090
:03016300000B632B
:00000001FF

View File

@@ -1 +0,0 @@
USB_FW.201.hex

View File

@@ -51,7 +51,7 @@ BEGIN { $init_dir = dirname($0); unshift(@INC, "$init_dir"); }
use XppConfig $init_dir;
my $unit_id;
my %opts;
my $eeprom_release_201 = 0;
my $vbat_48 = 0;
getopts('o:', \%opts);
@@ -59,7 +59,6 @@ my %settings;
$settings{debug} = 0;
$settings{fxs_skip_calib} = 0;
my $chipregs;
my $ring_registers;
sub logit {
print STDERR "$unit_id: @_\n";
@@ -95,7 +94,7 @@ if (-t STDERR) {
}
logit "XBUS_MODEL_STRING='$ENV{XBUS_MODEL_STRING}'";
if ($ENV{XBUS_MODEL_STRING} =~ m{.*/.*/201}) {
$eeprom_release_201 = 1;
$vbat_48 = 1;
}
$chipregs = sprintf "/sys/bus/xpds/devices/%02d:%1d:0/chipregs",
$ENV{XBUS_NUMBER}, $ENV{UNIT_NUMBER};
@@ -105,10 +104,6 @@ if (-t STDERR) {
logit "OLD DRIVER: does not use /sys chipregs. Falling back to /proc"
if -f $chipregs;
}
$ring_registers = sprintf "/sys/bus/xpds/devices/%02d:%1d:0/fxs_ring_registers",
$ENV{XBUS_NUMBER}, $ENV{UNIT_NUMBER};
logit "OLD DRIVER: missing '$ring_registers' -- fallback to hard-coded defaults"
unless -f $ring_registers;
}
sub set_output() {
@@ -152,16 +147,6 @@ sub write_to_slic_file($) {
}
sub write_to_ring_register($) {
my $write_str = shift;
open(SLICS,">$ring_registers") or
die("Failed writing to ring_registers file $ring_registers");
print SLICS $write_str;
close(SLICS) or die "Failed writing '$write_str' to '$ring_registers': $!";
main::mysleep(0.001);
}
sub read_reg($$$) {
my $read_slic = shift;
my $read_reg = shift;
@@ -307,13 +292,13 @@ sub init_indirect_registers() {
}
sub init_early_direct_regs() {
my $lbv = ($eeprom_release_201) ? "20" : "10";
my $vcm = ($eeprom_release_201) ? "02" : "03";
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 34 # High Battery Voltage
* WD 4A 3F # High Battery Voltage
* WD 4B $lbv # Low Battery Voltage
* WD 49 $vcm # Common Mode Voltage (VCM)
* WD 40 00 # Line Feed Control
@@ -457,10 +442,6 @@ sub check_slics() {
return @slics;
}
sub overwrite_ring_registers() {
write_to_ring_register("NEON 0x33 0x12");
}
package main;
main::debug "Starting '$0'";
@@ -489,7 +470,6 @@ while(<DATA>) {
print "$_\n";
}
close REG;
FXS::overwrite_ring_registers();
main::debug "Ending '$0'";
close STDERR;

View File

@@ -415,9 +415,6 @@ close STDERR;
exit 0;
__DATA__
* WD 12 02 # Full wave rectified ring detection
* WD 03 01 # Polarity reversal detect mask
* WD 04 00 # Clear interrupt status
* WD 21 08 # Disable PCM transfers
* WD 18 99
* WD 06 00

View File

@@ -7,9 +7,7 @@ static int mmap_match(struct device *dev, struct device_driver *driver)
{
return !strncmp(dev_name(dev), driver->name, strlen(driver->name));
}
static int mmap_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size)
static int mmap_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size)
{
envp[0] = buffer;
envp[1] = NULL;
@@ -35,6 +33,8 @@ static struct device mmap_bus = {
.release = mmap_bus_release,
};
int register_mmap_device(struct mmap_device *dev)
{
dev->dev.bus = &mmap_bus_type;
@@ -43,12 +43,12 @@ int register_mmap_device(struct mmap_device *dev)
strncpy(dev->dev.bus_id, dev->name, BUS_ID_SIZE);
return device_register(&dev->dev);
}
EXPORT_SYMBOL(register_mmap_device);
void unregister_mmap_device(struct mmap_device *dev)
{
device_unregister(&dev->dev);
}
EXPORT_SYMBOL(register_mmap_device);
EXPORT_SYMBOL(unregister_mmap_device);
int register_mmap_driver(struct mmap_driver *driver)
@@ -56,12 +56,12 @@ int register_mmap_driver(struct mmap_driver *driver)
driver->driver.bus = &mmap_bus_type;
return driver_register(&driver->driver);
}
EXPORT_SYMBOL(register_mmap_driver);
void unregister_mmap_driver(struct mmap_driver *driver)
{
driver_unregister(&driver->driver);
}
EXPORT_SYMBOL(register_mmap_driver);
EXPORT_SYMBOL(unregister_mmap_driver);
int register_mmap_bus(void)
@@ -78,13 +78,13 @@ bus_reg:
bus_type_reg:
return ret;
}
EXPORT_SYMBOL(register_mmap_bus);
void unregister_mmap_bus(void)
{
device_unregister(&mmap_bus);
bus_unregister(&mmap_bus_type);
}
EXPORT_SYMBOL(register_mmap_bus);
EXPORT_SYMBOL(unregister_mmap_bus);
MODULE_AUTHOR("Alexander Landau <landau.alex@gmail.com>");

View File

@@ -4,7 +4,6 @@
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/blackfin.h>
@@ -20,13 +19,11 @@
#include "xframe_queue.h"
/* Check at compile time that sizeof(xframe_t) is a multiple of 4 */
typedef char
sizeof_xframe_t_should_be_divisible_by_4[((sizeof(xframe_t) % 4) ==
0) * 2 - 1];
typedef char sizeof_xframe_t_should_be_divisible_by_4[((sizeof(xframe_t) % 4) == 0) * 2 - 1];
#define ssync() __builtin_bfin_ssync()
//#define AB_IN_BUF PF5
//#define AB_IN_BUF PF5
/* firmware pins */
#define DATA PG8
#define NCONFIG PG9
@@ -36,13 +33,13 @@ typedef char
#ifdef DEBUG_VIA_GPIO
/*
* For debugging we can use the following two pins.
* For debugging we can use the following two pins.
* These two pins are not used *after initialization*
*/
#define DEBUG_GPIO1 CONF_DONE
#define DEBUG_GPIO2 NSTATUS
static int rx_intr_counter;
static int rx_intr_counter;
#endif
#define FPGA_RX_IRQ IRQ_PF7
@@ -52,15 +49,9 @@ static int rx_intr_counter;
#define END_OF_FRAME 0x0001
#define GET_LEN 0x0002
#define START_RD_BURST 0x0008
/* stand alone Astribank without USB (Asterisk BlackFin Mode) */
#define AS_BF_MODE 0x0010
/*
* all data between Astribank and USB routed
* thru BF(EchoCanceler BlackFin Mode)
*/
#define EC_BF_MODE 0x0020
/* Astribank worke with USB only (no BlackFin Mode) */
#define NO_BF_MODE 0x0040
#define AS_BF_MODE 0x0010 //stand alone Astribank without USB (Asterisk BlackFin Mode)
#define EC_BF_MODE 0x0020 //all data between Astribank and USB routed thru BF(EchoCanceler BlackFin Mode)
#define NO_BF_MODE 0x0040 //Astribank worke with USB only (no BlackFin Mode)
#define SET_XA_DIR 0x0080
#define GET_XPD_STS 0x0100
#define GET_CHECKSUM 0x0200
@@ -89,8 +80,9 @@ static void print_buffer(const char *msg, const char *buf, int len)
{
int i;
printk(KERN_ERR "%s", msg);
for (i = 0; i < len; i++)
for (i = 0; i < len; i++) {
printk("%02X ", (unsigned char)buf[i]);
}
printk("\n");
}
@@ -104,8 +96,7 @@ static void update_counter(struct counter *c, struct timeval *tv1)
c->intr_min = diff;
if (c->intr_max < diff)
c->intr_max = diff;
c->intr_avg =
(c->intr_avg * c->intr_count + diff) / (c->intr_count + 1);
c->intr_avg = (c->intr_avg*c->intr_count + diff) / (c->intr_count+1);
c->intr_count++;
}
@@ -114,7 +105,7 @@ static irqreturn_t xpp_mmap_rx_irq(int irq, void *dev_id)
unsigned short rxcnt;
xbus_t *xbus;
xframe_t *xframe;
__u8 *buf;
byte *buf;
bool in_use = 0;
struct timeval tv1;
@@ -124,7 +115,7 @@ static irqreturn_t xpp_mmap_rx_irq(int irq, void *dev_id)
xbus = xbus_num(global_xbus->num);
BUG_ON(!xbus);
if (!XBUS_GET(xbus)) {
if(!XBUS_GET(xbus)) {
if (printk_ratelimit())
XBUS_ERR(xbus, "Dropping packet. Is shutting down.\n");
goto out;
@@ -138,7 +129,7 @@ static irqreturn_t xpp_mmap_rx_irq(int irq, void *dev_id)
NOTICE("Got %d bytes\n", rxcnt);
goto out;
}
if (rxcnt >= XFRAME_DATASIZE) {
if(rxcnt >= XFRAME_DATASIZE) {
if (printk_ratelimit())
ERR("Bad rxcnt=%d\n", rxcnt);
goto out;
@@ -162,22 +153,18 @@ static irqreturn_t xpp_mmap_rx_irq(int irq, void *dev_id)
outw(START_RD_BURST, FPGA_BASE_ADDR + 4);
insw((unsigned long)FPGA_BASE_ADDR, buf, rxcnt / 2);
#if 0
for (count = 0; count < rxcnt; count += 2) {
for (count = 0; count < rxcnt; count+=2) {
unsigned short v = inw(FPGA_BASE_ADDR);
buf[count] = v & 0xFF;
buf[count + 1] = v >> 8;
buf[count+1] = v >> 8;
}
#endif
if (rxcnt & 1)
buf[rxcnt - 1] = inw(FPGA_BASE_ADDR);
/*
* Sanity check: length of first packet in frame
* should be no more than the frame length
*/
if (((buf[0] | (buf[1] << 8)) & 0x3FF) > rxcnt) {
if (rxcnt & 1)
buf[rxcnt-1] = inw(FPGA_BASE_ADDR);
/* Sanity check: length of first packet in frame should be no more than the frame length */
if (((buf[0] | (buf[1]<<8)) & 0x3FF) > rxcnt) {
if (printk_ratelimit()) {
ERR("Packet len=%d, frame len=%d\n",
(buf[0] | (buf[1] << 8)) & 0x3FF, rxcnt);
ERR("Packet len=%d, frame len=%d\n", (buf[0] | (buf[1]<<8)) & 0x3FF, rxcnt);
print_buffer("16 bytes of packet: ", buf, 16);
}
goto free;
@@ -212,7 +199,7 @@ static void send_buffer(unsigned char *buf, unsigned long len)
print_buffer("Sent: ", buf, len);
outsw((unsigned long)FPGA_BASE_ADDR, buf, len / 2);
if (len & 1)
outw((unsigned short)buf[len - 1], FPGA_BASE_ADDR);
outw((unsigned short)buf[len-1], FPGA_BASE_ADDR);
outw(END_OF_FRAME, FPGA_BASE_ADDR + 4);
}
@@ -271,10 +258,7 @@ static int xframe_send_common(xbus_t *xbus, xframe_t *xframe, bool pcm)
if (pcm && pcm_in_pool_count >= 1) {
static int rate_limit;
if ((rate_limit++ % 1000) == 0)
XBUS_ERR(xbus,
"Dropped PCM xframe "
"(pcm_in_pool_count=%d).\n",
pcm_in_pool_count);
XBUS_ERR(xbus, "Dropped PCM xframe (pcm_in_pool_count=%d).\n", pcm_in_pool_count);
FREE_SEND_XFRAME(xbus, xframe);
pcm_dropped++;
} else {
@@ -282,9 +266,7 @@ static int xframe_send_common(xbus_t *xbus, xframe_t *xframe, bool pcm)
static int rate_limit;
spin_unlock_irqrestore(&tx_ready_lock, flags);
if ((rate_limit++ % 1000) == 0)
XBUS_ERR(xbus,
"Dropped xframe. "
"Cannot enqueue.\n");
XBUS_ERR(xbus, "Dropped xframe. Cannot enqueue.\n");
FREE_SEND_XFRAME(xbus, xframe);
return -E2BIG;
}
@@ -302,12 +284,10 @@ static xframe_t *alloc_xframe(xbus_t *xbus, gfp_t gfp_flags)
if (!xframe) {
static int rate_limit;
if ((rate_limit++ % 1000) < 5)
XBUS_ERR(xbus, "frame allocation failed (%d)\n",
rate_limit);
XBUS_ERR(xbus, "frame allocation failed (%d)\n", rate_limit);
return NULL;
}
xframe_init(xbus, xframe, ((__u8 *)xframe) + sizeof(xframe_t),
XFRAME_DATASIZE, xbus);
xframe_init(xbus, xframe, ((byte*)xframe) + sizeof(xframe_t), XFRAME_DATASIZE, xbus);
return xframe;
}
@@ -336,26 +316,28 @@ static struct xbus_ops xmmap_ops = {
static int fill_proc_queue(char *p, struct xframe_queue *q)
{
int len;
int len;
len = sprintf(p,
"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d "
"worst_lag %02ld.%ld ms\n",
q->name, q->steady_state_count, q->count, q->max_count,
q->worst_count, q->overflows, q->worst_lag_usec / 1000,
q->worst_lag_usec % 1000);
"%-15s: counts %3d, %3d, %3d worst %3d, overflows %3d worst_lag %02ld.%ld ms\n",
q->name,
q->steady_state_count,
q->count,
q->max_count,
q->worst_count,
q->overflows,
q->worst_lag_usec / 1000,
q->worst_lag_usec % 1000);
xframe_queue_clearstats(q);
return len;
}
static int fill_proc_counter(char *p, struct counter *c)
{
return sprintf(p, "min=%ld\nmax=%ld\navg=%ld\ncount=%ld\n", c->intr_min,
c->intr_max, c->intr_avg, c->intr_count);
return sprintf(p, "min=%ld\nmax=%ld\navg=%ld\ncount=%ld\n", c->intr_min, c->intr_max, c->intr_avg, c->intr_count);
}
static int xpp_mmap_proc_read(char *page, char **start, off_t off, int count,
int *eof, void *data)
static int xpp_mmap_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
len += fill_proc_queue(page + len, &txpool);
@@ -365,7 +347,7 @@ static int xpp_mmap_proc_read(char *page, char **start, off_t off, int count,
len += fill_proc_counter(page + len, &rx_counter);
len += sprintf(page + len, "\ntx_counter:\n");
len += fill_proc_counter(page + len, &tx_counter);
if (len <= off + count) {
if (len <= off+count) {
*eof = 1;
tx_counter.intr_min = rx_counter.intr_min = INT_MAX;
tx_counter.intr_max = rx_counter.intr_max = 0;
@@ -381,15 +363,14 @@ static int xpp_mmap_proc_read(char *page, char **start, off_t off, int count,
return len;
}
static int xpp_mmap_proc_write(struct file *file, const char __user *buffer,
unsigned long count, void *data)
static int xpp_mmap_proc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
int i = 0;
char *txchunk, *p, *endp;
if (count >= XFRAME_DATASIZE * 3 + 10)
if (count >= XFRAME_DATASIZE*3+10)
return -EINVAL;
p = txchunk = kmalloc(count + 1, GFP_KERNEL);
p = txchunk = kmalloc(count+1, GFP_KERNEL);
if (copy_from_user(txchunk, buffer, count)) {
count = -EFAULT;
goto out;
@@ -398,15 +379,13 @@ static int xpp_mmap_proc_write(struct file *file, const char __user *buffer,
while (*p) {
unsigned long value;
while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r')
p++;
if (*p == '\0')
break;
while (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') p++;
if (*p == '\0') break;
value = simple_strtoul(p, &endp, 16);
if (endp == p || value > 0xFF) {
INFO("%s: Bad input\n", __func__);
count = -EINVAL;
goto out;
INFO("%s: Bad input\n", __FUNCTION__);
count = -EINVAL;
goto out;
}
p = endp;
txchunk[i++] = (char)value;
@@ -420,8 +399,8 @@ out:
static struct mmap_driver astribank_driver = {
.module = THIS_MODULE,
.driver = {
.name = "xpp_mmap",
},
.name = "xpp_mmap",
},
};
static struct mmap_device astribank_dev = {
@@ -429,52 +408,42 @@ static struct mmap_device astribank_dev = {
.driver = &astribank_driver,
};
static int __init xpp_mmap_load_fpga(u8 * data, size_t size)
static int __init xpp_mmap_load_fpga(u8 *data, size_t size)
{
size_t i;
/* set data, nconfig and dclk to port out */
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DATA | NCONFIG | DCLK);
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DATA | NCONFIG | DCLK); //set data, nconfig and dclk to port out
bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~(DATA | NCONFIG | DCLK));
/* set conf_done and nstatus to port in */
bfin_write_PORTGIO_DIR(
bfin_read_PORTGIO_DIR() & ~(CONF_DONE | NSTATUS));
bfin_write_PORTGIO_INEN(
bfin_read_PORTGIO_INEN() & ~(DATA | NCONFIG | DCLK));
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() & ~(CONF_DONE | NSTATUS));//set conf_done and nstatus to port in
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & ~(DATA | NCONFIG | DCLK));
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() | CONF_DONE | NSTATUS);
/* reset fpga during configuration holds nCONFIG low */
bfin_write_PORTGIO_CLEAR(NCONFIG);
udelay(40); /* Tcfg ~40us delay */
/* transition nCONFIG to high - reset end. */
bfin_write_PORTGIO_SET(NCONFIG);
udelay(40); /* Tcf2ck ~40us delay */
bfin_write_PORTGIO_CLEAR(NCONFIG); //reset fpga during configuration holds nCONFIG low
udelay(40); //Tcfg ~40us delay
bfin_write_PORTGIO_SET(NCONFIG); //transition nCONFIG to high - reset end.
udelay(40); //Tcf2ck ~40us delay
if (!(bfin_read_PORTGIO() & NSTATUS))
return -EIO; /* report reset faill - Tcf2st1 pass */
return -EIO; //report reset faill - Tcf2st1 pass
#if 0
if (!(bfin_read_PORTGIO() & CONF_DONE))
return -EIO;
#endif
bfin_write_PORTGIO_CLEAR(DCLK);
for (i = 0; i < size; i++) { /* loop EP2OUT buffer data to FPGA */
for (i=0; i<size; i++) { // loop EP2OUT buffer data to FPGA
int j;
u8 __u8 = data[i];
/*
* Send the configuration data through the DATA0 pin
* one bit at a time.
*/
for (j = 0; j < 8; j++)
u8 byte = data[i];
for (j=0; j<8; j++) //send the configuration data through the DATA0 pin one bit at a time.
{
if (__u8 & 1)
if (byte & 1)
bfin_write_PORTGIO_SET(DATA);
else
bfin_write_PORTGIO_CLEAR(DATA);
__u8 >>= 1;
byte >>= 1;
bfin_write_PORTGIO_SET(DCLK);
bfin_write_PORTGIO_CLEAR(DCLK);
}
if (!(bfin_read_PORTGIO() & NSTATUS))
return -EIO; /* check the nSTATUS */
return -EIO; //check the nSTATUS
}
bfin_write_PORTGIO_CLEAR(DATA);
udelay(1);
@@ -486,29 +455,20 @@ static int __init xpp_mmap_load_fpga(u8 * data, size_t size)
* some pins that were used only during initialization
* to be used for debugging from now on.
*/
/* set to port out */
bfin_write_PORTGIO_DIR(
bfin_read_PORTGIO_DIR() | DEBUG_GPIO1 | DEBUG_GPIO2);
bfin_write_PORTG_FER(bfin_read_PORTG_FER() &
~(DEBUG_GPIO1 | DEBUG_GPIO2));
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() &
~(DEBUG_GPIO1 | DEBUG_GPIO2));
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() | DEBUG_GPIO1 | DEBUG_GPIO2); //set to port out
bfin_write_PORTG_FER(bfin_read_PORTG_FER() & ~(DEBUG_GPIO1 | DEBUG_GPIO2));
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & ~(DEBUG_GPIO1 | DEBUG_GPIO2));
#endif
udelay(40); /* tCD2UM - CONF_DONE high to user mode */
udelay(40); //tCD2UM - CONF_DONE high to user mode
return 0;
}
static void __exit xpp_mmap_unload_fpga(void)
{
/* reset fpga during configuration holds nCONFIG low */
bfin_write_PORTGIO_CLEAR(NCONFIG);
udelay(40); /* Tcfg ~40us delay */
/* disable output pin */
bfin_write_PORTGIO_DIR(
bfin_read_PORTGIO_DIR() & ~(DATA | NCONFIG | DCLK));
/* disable input buffer */
bfin_write_PORTGIO_INEN(
bfin_read_PORTGIO_INEN() & ~(CONF_DONE | NSTATUS));
bfin_write_PORTGIO_CLEAR(NCONFIG); //reset fpga during configuration holds nCONFIG low
udelay(40); //Tcfg ~40us delay
bfin_write_PORTGIO_DIR(bfin_read_PORTGIO_DIR() & ~( DATA | NCONFIG | DCLK)); //disable output pin
bfin_write_PORTGIO_INEN(bfin_read_PORTGIO_INEN() & ~( CONF_DONE | NSTATUS));//disable input buffer
INFO("FPGA Firmware unloaded\n");
}
@@ -516,8 +476,7 @@ static int __init xpp_mmap_load_firmware(void)
{
const struct firmware *fw;
int ret;
if ((ret =
request_firmware(&fw, "astribank.bin", &astribank_dev.dev)) < 0)
if ((ret = request_firmware(&fw, "astribank.bin", &astribank_dev.dev)) < 0)
return ret;
xpp_mmap_load_fpga(fw->data, fw->size);
release_firmware(fw);
@@ -539,33 +498,29 @@ static int __init xpp_mmap_init(void)
ERR("xpp_mmap_load_firmware() failed, errno=%d\n", ret);
goto fail_fw;
}
if ((ret =
request_irq(FPGA_RX_IRQ, xpp_mmap_rx_irq, IRQF_TRIGGER_RISING,
"xpp_mmap_rx", NULL)) < 0) {
if ((ret = request_irq(FPGA_RX_IRQ, xpp_mmap_rx_irq, IRQF_TRIGGER_RISING, "xpp_mmap_rx", NULL)) < 0) {
ERR("Unable to attach to RX interrupt %d\n", FPGA_RX_IRQ);
goto fail_irq_rx;
}
if ((ret =
request_irq(FPGA_TX_IRQ, xpp_mmap_tx_irq, IRQF_TRIGGER_RISING,
"xpp_mmap_tx", NULL)) < 0) {
if ((ret = request_irq(FPGA_TX_IRQ, xpp_mmap_tx_irq, IRQF_TRIGGER_RISING, "xpp_mmap_tx", NULL)) < 0) {
ERR("Unable to attach to TX interrupt %d\n", FPGA_TX_IRQ);
goto fail_irq_tx;
}
if (!request_region((resource_size_t) FPGA_BASE_ADDR, 8, "xpp_mmap")) {
if (!request_region((resource_size_t)FPGA_BASE_ADDR, 8, "xpp_mmap")) {
ERR("Unable to request memory region at %p\n", FPGA_BASE_ADDR);
goto fail_region;
}
outw(AS_BF_MODE, FPGA_BASE_ADDR + 4);
outw(AS_BF_MODE, FPGA_BASE_ADDR + 4);
xframe_cache =
kmem_cache_create("xframe_cache",
sizeof(xframe_t) + XFRAME_DATASIZE, 0, 0,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)
NULL,
xframe_cache = kmem_cache_create("xframe_cache",
sizeof(xframe_t) + XFRAME_DATASIZE,
0, 0,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
NULL,
#endif
NULL);
if (!xframe_cache) {
NULL);
if(!xframe_cache) {
ret = -ENOMEM;
goto fail_cache;
}
@@ -577,11 +532,9 @@ static int __init xpp_mmap_init(void)
}
strncpy(global_xbus->connector, "mmap", XBUS_DESCLEN);
strncpy(global_xbus->label, "mmap:0", LABEL_SIZE);
xframe_queue_init(&txpool, 10, 200, "mmap_txpool", global_xbus);
if (!
(proc_entry =
create_proc_entry("xpp_mmap", 0, global_xbus->proc_xbus_dir))) {
if (!(proc_entry = create_proc_entry("xpp_mmap", 0, global_xbus->proc_xbus_dir))) {
ERR("create_proc_entry() failed\n");
ret = -EINVAL;
goto fail_proc;
@@ -599,7 +552,7 @@ fail_proc:
fail_xbus:
kmem_cache_destroy(xframe_cache);
fail_cache:
release_region((resource_size_t) FPGA_BASE_ADDR, 8);
release_region((resource_size_t)FPGA_BASE_ADDR, 8);
fail_region:
free_irq(FPGA_TX_IRQ, NULL);
fail_irq_tx:
@@ -626,7 +579,7 @@ static void __exit xpp_mmap_exit(void)
xbus_disconnect(xbus);
kmem_cache_destroy(xframe_cache);
release_region((resource_size_t) FPGA_BASE_ADDR, 8);
release_region((resource_size_t)FPGA_BASE_ADDR, 8);
free_irq(FPGA_RX_IRQ, NULL);
free_irq(FPGA_TX_IRQ, NULL);

View File

@@ -20,26 +20,31 @@
*
*/
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
# warning "This module is tested only with 2.6 kernels"
#endif
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/parport.h>
#include "parport_debug.h"
static struct parport *debug_sync_parport;
static int parport_toggles[8]; /* 8 bit flip-flop */
static struct parport *debug_sync_parport = NULL;
static int parport_toggles[8]; /* 8 bit flip-flop */
void flip_parport_bit(unsigned char bitnum)
{
static unsigned char last_value;
static unsigned char last_value;
DEFINE_SPINLOCK(lock);
unsigned long flags;
unsigned char mask;
unsigned char value;
unsigned long flags;
unsigned char mask;
unsigned char value;
if (!debug_sync_parport) {
if (printk_ratelimit()) {
if(!debug_sync_parport) {
if(printk_ratelimit()) {
printk(KERN_NOTICE "%s: no debug parallel port\n",
THIS_MODULE->name);
THIS_MODULE->name);
}
return;
}
@@ -47,7 +52,7 @@ void flip_parport_bit(unsigned char bitnum)
mask = 1 << bitnum;
spin_lock_irqsave(&lock, flags);
value = last_value & ~mask;
if (parport_toggles[bitnum] % 2) /* square wave */
if(parport_toggles[bitnum] % 2) /* square wave */
value |= mask;
last_value = value;
parport_toggles[bitnum]++;
@@ -58,11 +63,10 @@ EXPORT_SYMBOL(flip_parport_bit);
static void parport_attach(struct parport *port)
{
printk(KERN_INFO "%s: Using %s for debugging\n", THIS_MODULE->name,
port->name);
if (debug_sync_parport) {
printk(KERN_INFO "%s: Using %s for debugging\n", THIS_MODULE->name, port->name);
if(debug_sync_parport) {
printk(KERN_ERR "%s: Using %s, ignore new attachment %s\n",
THIS_MODULE->name, debug_sync_parport->name, port->name);
THIS_MODULE->name, debug_sync_parport->name, port->name);
return;
}
parport_get_port(port);
@@ -72,16 +76,16 @@ static void parport_attach(struct parport *port)
static void parport_detach(struct parport *port)
{
printk(KERN_INFO "%s: Releasing %s\n", THIS_MODULE->name, port->name);
if (debug_sync_parport != port) {
if(debug_sync_parport != port) {
printk(KERN_ERR "%s: Using %s, ignore new detachment %s\n",
THIS_MODULE->name, debug_sync_parport->name, port->name);
THIS_MODULE->name, debug_sync_parport->name, port->name);
return;
}
parport_put_port(debug_sync_parport);
debug_sync_parport = NULL;
}
static struct parport_driver debug_parport_driver = {
static struct parport_driver debug_parport_driver = {
.name = "parport_debug",
.attach = parport_attach,
.detach = parport_detach,
@@ -89,7 +93,7 @@ static struct parport_driver debug_parport_driver = {
int __init parallel_dbg_init(void)
{
int ret;
int ret;
ret = parport_register_driver(&debug_parport_driver);
return ret;

View File

@@ -28,4 +28,4 @@ void flip_parport_bit(unsigned char bitnum);
#define flip_parport_bit(bitnum)
#endif
#endif /* PARPORT_DEBUG_H */
#endif /* PARPORT_DEBUG_H */

View File

@@ -3,35 +3,30 @@
int main(int argc, char *argv[])
{
size_t i;
for (i = 0; i < (sizeof(fxo_modes) / sizeof(struct fxo_mode)); i++) {
if (fxo_modes[i].name == NULL)
break;
int reg16 = 0, reg26 = 0, reg30 = 0, reg31 = 0x20;
char ring_osc[BUFSIZ] = "", ring_x[BUFSIZ] = "";
for (i=0; i<(sizeof(fxo_modes)/sizeof(struct fxo_mode)); i++) {
if (fxo_modes[i].name == NULL) break;
int reg16=0, reg26=0, reg30=0, reg31=0x20;
char ring_osc[BUFSIZ]="", ring_x[BUFSIZ] = "";
reg16 |= (fxo_modes[i].ohs << 6);
reg16 |= (fxo_modes[i].rz << 1);
reg16 |= (fxo_modes[i].rt);
reg26 |= (fxo_modes[i].dcv << 6);
reg26 |= (fxo_modes[i].mini << 4);
reg26 |= (fxo_modes[i].ilim << 1);
reg30 = (fxo_modes[i].acim);
reg31 |= (fxo_modes[i].ohs2 << 3);
if (fxo_modes[i].ring_osc)
snprintf(ring_osc, BUFSIZ, "ring_osc=%04X",
fxo_modes[i].ring_osc);
snprintf(ring_osc, BUFSIZ, "ring_osc=%04X", fxo_modes[i].ring_osc);
if (fxo_modes[i].ring_x)
snprintf(ring_x, BUFSIZ, "ring_x=%04X",
fxo_modes[i].ring_x);
printf("%-15s\treg16=%02X\treg26=%02X\treg30=%02X\t"
"reg31=%02X\t%s\t%s\n",
fxo_modes[i].name, reg16, reg26, reg30, reg31,
ring_osc, ring_x);
snprintf(ring_x, BUFSIZ, "ring_x=%04X", fxo_modes[i].ring_x);
printf("%-15s\treg16=%02X\treg26=%02X\treg30=%02X\treg31=%02X\t%s\t%s\n",
fxo_modes[i].name, reg16, reg26, reg30, reg31, ring_osc, ring_x);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,10 +39,10 @@ struct xbus_workqueue;
#ifdef __KERNEL__
struct xbus_ops {
int (*xframe_send_pcm) (xbus_t *xbus, xframe_t *xframe);
int (*xframe_send_cmd) (xbus_t *xbus, xframe_t *xframe);
xframe_t *(*alloc_xframe) (xbus_t *xbus, gfp_t gfp_flags);
void (*free_xframe) (xbus_t *xbus, xframe_t *xframe);
int (*xframe_send_pcm)(xbus_t *xbus, xframe_t *xframe);
int (*xframe_send_cmd)(xbus_t *xbus, xframe_t *xframe);
xframe_t *(*alloc_xframe)(xbus_t *xbus, gfp_t gfp_flags);
void (*free_xframe)(xbus_t *xbus, xframe_t *xframe);
};
/*
@@ -67,11 +67,19 @@ enum {
/* yucky, make an instance so we can size it... */
static struct xbus_counters {
char *name;
char *name;
} xbus_counters[] = {
C_(UNITS), C_(TX_XFRAME_PCM), C_(RX_XFRAME_PCM), C_(TX_PACK_PCM),
C_(RX_PACK_PCM), C_(TX_BYTES), C_(RX_BYTES),
C_(TX_PCM_FRAG), C_(RX_CMD), C_(TX_CMD),};
C_(UNITS),
C_(TX_XFRAME_PCM),
C_(RX_XFRAME_PCM),
C_(TX_PACK_PCM),
C_(RX_PACK_PCM),
C_(TX_BYTES),
C_(RX_BYTES),
C_(TX_PCM_FRAG),
C_(RX_CMD),
C_(TX_CMD),
};
#undef C_
@@ -91,17 +99,17 @@ enum xbus_state {
const char *xbus_statename(enum xbus_state st);
struct xbus_transport {
struct xbus_ops *ops;
void *priv;
struct device *transport_device;
ushort max_send_size;
enum xbus_state xbus_state;
unsigned long transport_flags;
spinlock_t state_lock;
atomic_t transport_refcount;
wait_queue_head_t transport_unused;
spinlock_t lock;
char model_string[MAX_ENV_STR];
struct xbus_ops *ops;
void *priv;
struct device *transport_device;
ushort max_send_size;
enum xbus_state xbus_state;
unsigned long transport_flags;
spinlock_t state_lock;
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)
@@ -110,8 +118,7 @@ struct xbus_transport {
#define TRANSPORT_EXIST(xbus) ((xbus)->transport.ops != NULL)
#define XBUS_FLAG_CONNECTED 0
#define XBUS_FLAGS(xbus, flg) \
test_bit(XBUS_FLAG_ ## flg, &((xbus)->transport.transport_flags))
#define XBUS_FLAGS(xbus, flg) test_bit(XBUS_FLAG_ ## flg, &((xbus)->transport.transport_flags))
struct xbus_ops *transportops_get(xbus_t *xbus);
void transportops_put(xbus_t *xbus);
@@ -120,39 +127,35 @@ void transportops_put(xbus_t *xbus);
* Encapsulate all poll related data of a single xbus.
*/
struct xbus_workqueue {
struct workqueue_struct *wq;
struct work_struct xpds_init_work;
bool xpds_init_done;
struct list_head card_list;
int num_units;
int num_units_initialized;
wait_queue_head_t wait_for_xpd_initialization;
spinlock_t worker_lock;
struct semaphore running_initialization;
struct workqueue_struct *wq;
struct work_struct xpds_init_work;
bool xpds_init_done;
struct list_head card_list;
int num_units;
int num_units_initialized;
wait_queue_head_t wait_for_xpd_initialization;
spinlock_t worker_lock;
struct semaphore running_initialization;
};
/*
* Allocate/Free an xframe from pools of empty xframes.
* Calls to {get, put}_xframe are wrapped in
* Calls to {get,put}_xframe are wrapped in
* the macros bellow, so we take/return it
* to the correct pool.
*/
xframe_t *get_xframe(struct xframe_queue *q);
void put_xframe(struct xframe_queue *q, xframe_t *xframe);
#define ALLOC_SEND_XFRAME(xbus) \
get_xframe(&(xbus)->send_pool)
#define ALLOC_RECV_XFRAME(xbus) \
get_xframe(&(xbus)->receive_pool)
#define FREE_SEND_XFRAME(xbus, xframe) \
put_xframe(&(xbus)->send_pool, (xframe))
#define FREE_RECV_XFRAME(xbus, xframe) \
put_xframe(&(xbus)->receive_pool, (xframe))
#define ALLOC_SEND_XFRAME(xbus) get_xframe(&(xbus)->send_pool)
#define ALLOC_RECV_XFRAME(xbus) get_xframe(&(xbus)->receive_pool)
#define FREE_SEND_XFRAME(xbus, xframe) put_xframe(&(xbus)->send_pool, (xframe))
#define FREE_RECV_XFRAME(xbus, xframe) put_xframe(&(xbus)->receive_pool, (xframe))
xbus_t *xbus_num(uint num);
xbus_t *get_xbus(const char *msg, uint num);
void put_xbus(const char *msg, xbus_t *xbus);
int refcount_xbus(xbus_t *xbus);
xbus_t *xbus_num(uint num);
xbus_t *get_xbus(const char *msg, uint num);
void put_xbus(const char *msg, xbus_t *xbus);
int refcount_xbus(xbus_t *xbus);
/*
* Echo canceller related data
@@ -160,17 +163,17 @@ int refcount_xbus(xbus_t *xbus);
#define ECHO_TIMESLOTS 128
struct echoops {
int (*ec_set) (xpd_t *xpd, int pos, bool on);
int (*ec_get) (xpd_t *xpd, int pos);
int (*ec_update) (xbus_t *xbus);
void (*ec_dump) (xbus_t *xbus);
int (*ec_set)(xpd_t *xpd, int pos, bool on);
int (*ec_get)(xpd_t *xpd, int pos);
int (*ec_update)(xbus_t *xbus);
void (*ec_dump)(xbus_t *xbus);
};
struct xbus_echo_state {
const struct echoops *echoops;
__u8 timeslots[ECHO_TIMESLOTS];
int xpd_idx;
struct device_attribute *da[MAX_XPDS];
const struct echoops *echoops;
byte timeslots[ECHO_TIMESLOTS];
int xpd_idx;
struct device_attribute *da[MAX_XPDS];
};
#define ECHOOPS(xbus) ((xbus)->echo_state.echoops)
#define EC_METHOD(name, xbus) (ECHOOPS(xbus)->name)
@@ -180,128 +183,126 @@ struct xbus_echo_state {
* An xbus is a transport layer for Xorcom Protocol commands
*/
struct xbus {
char busname[XBUS_NAMELEN]; /* set by xbus_new() */
char busname[XBUS_NAMELEN]; /* set by xbus_new() */
/* low-level bus drivers set these 2 fields */
char connector[XBUS_DESCLEN];
char label[LABEL_SIZE];
__u8 revision; /* Protocol revision */
struct xbus_transport transport;
struct dahdi_device *ddev;
char connector[XBUS_DESCLEN];
char label[LABEL_SIZE];
byte revision; /* Protocol revision */
struct xbus_transport transport;
struct dahdi_device *ddev;
int num;
struct xpd *xpds[MAX_XPDS];
struct xbus_echo_state echo_state;
int num;
struct xpd *xpds[MAX_XPDS];
struct xbus_echo_state echo_state;
int command_tick_counter;
int usec_nosend; /* Firmware flow control */
struct xframe_queue command_queue;
wait_queue_head_t command_queue_empty;
int command_tick_counter;
int usec_nosend; /* Firmware flow control */
struct xframe_queue command_queue;
wait_queue_head_t command_queue_empty;
struct xframe_queue send_pool; /* empty xframes for send */
struct xframe_queue receive_pool; /* empty xframes for receive */
struct xframe_queue send_pool; /* empty xframes for send */
struct xframe_queue receive_pool; /* empty xframes for receive */
/* tasklet processing */
struct xframe_queue receive_queue;
struct tasklet_struct receive_tasklet;
int cpu_rcv_intr[NR_CPUS];
int cpu_rcv_tasklet[NR_CPUS];
struct xframe_queue receive_queue;
struct tasklet_struct receive_tasklet;
int cpu_rcv_intr[NR_CPUS];
int cpu_rcv_tasklet[NR_CPUS];
struct quirks {
unsigned int has_fxo:1;
unsigned int has_digital_span:1;
} quirks;
bool self_ticking;
enum sync_mode sync_mode;
} quirks;
bool self_ticking;
enum sync_mode sync_mode;
/* Managed by low-level drivers: */
enum sync_mode sync_mode_default;
struct timer_list command_timer;
unsigned int xbus_frag_count;
struct xframe_queue pcm_tospan;
enum sync_mode sync_mode_default;
struct timer_list command_timer;
unsigned int xbus_frag_count;
struct xframe_queue pcm_tospan;
struct xpp_ticker ticker; /* for tick rate */
struct xpp_drift drift; /* for tick offset */
struct xpp_ticker ticker; /* for tick rate */
struct xpp_drift drift; /* for tick offset */
atomic_t pcm_rx_counter;
unsigned int global_counter;
atomic_t pcm_rx_counter;
unsigned int global_counter;
/* Device-Model */
struct device astribank;
struct device astribank;
#define dev_to_xbus(dev) container_of(dev, struct xbus, astribank)
struct kref kref;
struct kref kref;
#define kref_to_xbus(k) container_of(k, struct xbus, kref)
spinlock_t lock;
spinlock_t lock;
/* PCM metrics */
struct timeval last_tx_sync;
struct timeval last_rx_sync;
unsigned long max_tx_sync;
unsigned long min_tx_sync;
unsigned long max_rx_sync;
unsigned long min_rx_sync;
unsigned long max_rx_process; /* packet processing time (usec) */
struct timeval last_tx_sync;
struct timeval last_rx_sync;
unsigned long max_tx_sync;
unsigned long min_tx_sync;
unsigned long max_rx_sync;
unsigned long min_rx_sync;
unsigned long max_rx_process; /* packet processing time (usec) */
#ifdef SAMPLE_TICKS
#define SAMPLE_SIZE 1000
int sample_ticks[SAMPLE_SIZE];
bool sample_running;
int sample_pos;
int sample_ticks[SAMPLE_SIZE];
bool sample_running;
int sample_pos;
#endif
struct xbus_workqueue worker;
struct xbus_workqueue worker;
/*
* Sync adjustment
*/
int sync_adjustment;
int sync_adjustment_offset;
long pll_updated_at;
int sync_adjustment;
int sync_adjustment_offset;
long pll_updated_at;
atomic_t num_xpds;
atomic_t num_xpds;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_xbus_dir;
struct proc_dir_entry *proc_xbus_summary;
struct proc_dir_entry *proc_xbus_dir;
struct proc_dir_entry *proc_xbus_summary;
#ifdef PROTOCOL_DEBUG
struct proc_dir_entry *proc_xbus_command;
struct proc_dir_entry *proc_xbus_command;
#endif
#endif
/* statistics */
int counters[XBUS_COUNTER_MAX];
int counters[XBUS_COUNTER_MAX];
};
#endif
#define XFRAME_MAGIC 123456L
struct xframe {
unsigned long xframe_magic;
struct list_head frame_list;
atomic_t frame_len;
xbus_t *xbus;
struct timeval tv_created;
struct timeval tv_queued;
struct timeval tv_submitted;
struct timeval tv_received;
unsigned long xframe_magic;
struct list_head frame_list;
atomic_t frame_len;
xbus_t *xbus;
struct timeval tv_created;
struct timeval tv_queued;
struct timeval tv_submitted;
struct timeval tv_received;
/* filled by transport layer */
size_t frame_maxlen;
__u8 *packets; /* max XFRAME_DATASIZE */
__u8 *first_free;
int usec_towait; /* prevent overflowing AB */
void *priv;
size_t frame_maxlen;
byte *packets; /* max XFRAME_DATASIZE */
byte *first_free;
int usec_towait; /* prevent overflowing AB */
void *priv;
};
void xframe_init(xbus_t *xbus, xframe_t *xframe, void *buf, size_t maxsize,
void *priv);
void xframe_init(xbus_t *xbus, xframe_t *xframe, void *buf, size_t maxsize, void *priv);
#define XFRAME_LEN(frame) atomic_read(&(frame)->frame_len)
int xbus_core_init(void); /* Initializer */
void xbus_core_shutdown(void); /* Terminator */
int xbus_core_init(void); /* Initializer */
void xbus_core_shutdown(void); /* Terminator */
/* Frame handling */
void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe,
int debug);
void dump_xframe(const char msg[], const xbus_t *xbus, const xframe_t *xframe, int debug);
int send_cmd_frame(xbus_t *xbus, xframe_t *xframe);
/*
@@ -315,45 +316,58 @@ xpacket_t *xframe_next_packet(xframe_t *xframe, int len);
/*
* Map: unit+subunit <--> index in xbus->xpds[]
*/
#define XPD_IDX(unit, subunit) ((unit) * MAX_SUBUNIT + (subunit))
#define XPD_IDX(unit,subunit) ((unit) * MAX_SUBUNIT + (subunit))
#define XBUS_UNIT(idx) ((idx) / MAX_SUBUNIT)
#define XBUS_SUBUNIT(idx) ((idx) % MAX_SUBUNIT)
xpd_t *xpd_of(const xbus_t *xbus, int xpd_num);
xpd_t *xpd_byaddr(const xbus_t *xbus, uint unit, uint subunit);
int xbus_check_unique(xbus_t *xbus);
bool xbus_setstate(xbus_t *xbus, enum xbus_state newstate);
bool xbus_setflags(xbus_t *xbus, int flagbit, bool on);
xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size,
struct device *transport_device, void *priv);
void xbus_free(xbus_t *xbus);
int xbus_connect(xbus_t *xbus);
int xbus_activate(xbus_t *xbus);
void xbus_deactivate(xbus_t *xbus);
void xbus_disconnect(xbus_t *xbus);
void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe);
int xbus_process_worker(xbus_t *xbus);
int waitfor_xpds(xbus_t *xbus, char *buf);
xpd_t *xpd_of(const xbus_t *xbus, int xpd_num);
xpd_t *xpd_byaddr(const xbus_t *xbus, uint unit, uint subunit);
int xbus_check_unique(xbus_t *xbus);
bool xbus_setstate(xbus_t *xbus, enum xbus_state newstate);
bool xbus_setflags(xbus_t *xbus, int flagbit, bool on);
xbus_t *xbus_new(struct xbus_ops *ops, ushort max_send_size, struct device *transport_device, void *priv);
void xbus_free(xbus_t *xbus);
int xbus_connect(xbus_t *xbus);
int xbus_activate(xbus_t *xbus);
void xbus_deactivate(xbus_t *xbus);
void xbus_disconnect(xbus_t *xbus);
void xbus_receive_xframe(xbus_t *xbus, xframe_t *xframe);
int xbus_process_worker(xbus_t *xbus);
int waitfor_xpds(xbus_t *xbus, char *buf);
int xbus_xpd_bind(xbus_t *xbus, xpd_t *xpd, int unit, int subunit);
int xbus_xpd_unbind(xbus_t *xbus, xpd_t *xpd);
int xbus_xpd_bind(xbus_t *xbus, xpd_t *xpd, int unit, int subunit);
int xbus_xpd_unbind(xbus_t *xbus, xpd_t *xpd);
/* sysfs */
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 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 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);
void xbus_sysfs_transport_remove(xbus_t *xbus);
int xbus_sysfs_create(xbus_t *xbus);
void xbus_sysfs_remove(xbus_t *xbus);
int xpp_driver_init(void);
void xpp_driver_exit(void);
int xbus_sysfs_transport_create(xbus_t *xbus);
void xbus_sysfs_transport_remove(xbus_t *xbus);
int xbus_sysfs_create(xbus_t *xbus);
void xbus_sysfs_remove(xbus_t *xbus);
void astribank_uevent_send(xbus_t *xbus, enum kobject_action act);
#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
void astribank_uevent_send(xbus_t *xbus, enum kobject_action act);
#endif /* XBUS_CORE_H */
#endif /* XBUS_CORE_H */

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