Compare commits

...

28 Commits

Author SHA1 Message Date
Shaun Ruffell
396d4580b8 Use autotagged externals
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/tags/2.5.1-rc1@10612 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-28 20:13:08 +00:00
Shaun Ruffell
9c7a24f901 Importing files for 2.5.1-rc1 release.
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/tags/2.5.1-rc1@10611 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-28 20:12:56 +00:00
Shaun Ruffell
e0c5ee7b0c Creating tag for the release of dahdi-tools-2.5.1-rc1
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/tags/2.5.1-rc1@10610 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-28 20:12:09 +00:00
Oron Peled
c4fe52e769 xpp: astribank_hook: wait for udev to settle
When running the astribank_hook (only on Astribanks, in XPP_HOTPLUG_DAHDI
mode), wait for all other Astribanks to create all the required device
files.

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=10585

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10595 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-22 18:58:39 +00:00
Tzafrir Cohen
c57672cd88 xpp: astribank_allow: useless debug on write
Remove a useless debug message in the "write" operation.

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

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10554 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 11:43:35 +00:00
Tzafrir Cohen
c256218779 xpp: fix build warnings
Unlike original: also fixed fpga_load.

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

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10546 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 06:02:41 +00:00
Tzafrir Cohen
261869a437 xpp: oct612x: fix build warnings
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10545 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-20 05:54:32 +00:00
Oron Peled
57749f1c26 xpp: Update product ID's in Dahdi::Hardware::USB
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=10505

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10514 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:22:05 +00:00
Oron Peled
6da1f767e5 xpp: fix manpage of astribank_hexload
* Fixed 'astribanks_tool' string

Signed-off-by: Oron Peled <oron.peled@xorcom.com>
Origin: http://svnview.digium.com/svn/dahdi?view=rev&rev=10503

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10513 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:21:27 +00:00
Oron Peled
3a147a35c2 xpp: Customizable license markers
* License strings markers (BEGIN.../END...) can be customized
* By default, generate a "generic" license markers
* We accept any (paired) markers from the valid list

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=10502

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10512 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:21:06 +00:00
Oron Peled
a8c8435ea8 xpp: bugfix: handle echo_loader errors
* I/O errors of the device were not propagated up by echo_loader
* As a result, Octasic load failure did not prevented USB renumeration
* Make consistent return values:
  - In our functions: ret < 0 is error
  - In Octasic functions (UINT32): return Octasic error codes
* All error paths prints error messages (so we see how the error propagates)
* Also changed error order testing in init_octasic():
  Return status should be tested before the values of by-reference parameters

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=10499

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10510 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:19:34 +00:00
Oron Peled
0124097dfc xpp: echo_loader.c: add AB id to messages
* Define new macros AB_INFO(), AB_ERR() that prefix their message
  with the astribank information (usb device + serial number)
* Replace all INFO()/ERR() messages in echo_loader.c with the new macros

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=10498

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10509 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:18:10 +00:00
Oron Peled
a09b124790 xpp: xpp_fxloader: improve output
* Replaced (almost) all $LOGGER to echo:
  - In interactive use -- that what we want anyway
  - When called from UDEV, the subprocess stdout/stderr is piped to
    $LOGGER anyway (at the end of the script)
  - No need for many $LOGGER instances (each with its own pid)

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=10495

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10508 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:17:46 +00:00
Oron Peled
c5b905b1bf xpp: clean 'Extrainfo' EEPROM field
* Extrainfo field contains junk data
* Caused by:
  - The field is initialized to 0xFF values
  - There was no null termination (and no room to add it)
* New code:
  - Ensure that show_extrainfo() have null termination even if EEPROM
    field is full.
  - Replace trailing 0xFF characters with '\0' when reading this field
  - Since our default burned EEPROM contain Extrainfo field full of
    0xFF characters, this would make them look as null filled.

Internal Issue-Id: #1341
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=10491

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10507 17933a7a-c749-41c5-a318-cba88f637d49
2012-03-15 21:17:10 +00:00
Oron Peled
e0485bafc0 xpp: improved waitfor_xpds
* Fix an issue due to long firmware load time:
  - When one Astribank has an echo canceler (long firmware loading) and
    and another one does not.
  - The EC-less Astribank finishes initialization before the Astribank
    with EC is detected.
  - Thus waitfor_xpds terminates too early.

* We now iteratively build two sets of serial numbers:
  - One from wha we see in all Xorcom (e4e4:11[3456]x) USB devices.
  - The other is those that were detected in the driver.
  - Only when the two sets are equal (and > 0) we know we are done.
  - This is resilient to many problems (e.g: disconnect/reconnect of
    same device during initialization).

* The progress output was also improved: Now each detected AB
  show the total number so far.

* The timeout was also increased to 100sec

* Woraround for an Astribank with no serial (but just a single one on
  the system).

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=10465

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10467 17933a7a-c749-41c5-a318-cba88f637d49
2012-02-22 20:23:16 +00:00
Tzafrir Cohen
d6dafbdcea xpp: two extra product IDs: 1112, 1164
Two extra USB product IDs used in some odd maintenance scenarios.

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10371 17933a7a-c749-41c5-a318-cba88f637d49
2011-12-04 17:26:14 +00:00
Tzafrir Cohen
d1d22bf4f6 xpp: xpp_fxloader: regressions from r10355
* Avoid a duplicated run of udev on some systems.
* Fix usage of astribank_tool's output.

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10370 17933a7a-c749-41c5-a318-cba88f637d49
2011-12-04 17:25:49 +00:00
Tzafrir Cohen
cdbea31d0b Fix GCC 4.6 "set but not used" warnings
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10357 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-30 10:27:19 +00:00
Tzafrir Cohen
b229de1beb xpp: recovery firmware in xpp_fxloader
USB_RECOV.hex is an extra firmware that may be useful for recovering
from certain Astribank hardware faults in some scenarios. This adds
support for either loading it manually
('/usr/share/dahdi/xpp_fxloader recover-sb') or through udev, *if*
the required udev rules were set on the system.

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10356 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-30 10:25:40 +00:00
Tzafrir Cohen
04d6bc2893 xpp: Serialized Parallel load; E-Main-3 firmware
This introduces support for loading multiple firmwares in parallel also
for the case of a manual load. This is anyway the case for an automatic
load from udev.

* libusb needs to scan the bus all too often. This causes occasional
  failures for opening devices.
* Thus introduce a semaphore to serialize uses of libusb.

E-Main-3 firmware differs by a different value of bcdDevice:

* Read this from the sysfs devices tree.
* Fall back to lsusb -v (much slower) is sysfs not available.

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10355 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-30 10:25:16 +00:00
Tzafrir Cohen
ff25216d3a xpp: astribank_hexload: we need more lines
* Newer firmwares may have more lines.
* While we're at it, add better debug printing.
* Remove some unused debugging code.

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10354 17933a7a-c749-41c5-a318-cba88f637d49
2011-11-30 10:23:44 +00:00
Shaun Ruffell
2f10cda05a dahdi_genconf: Use 'dahdi_scan' to determine span_type for B410P cards.
The wcb4xxp driver does not put enough information in the proc filesystem to
determine if the ports are in TE or NT mode.  Previously the ports would
always just setup the dahdi-channels.conf file in TE mode. After this change
the dahdi_scan utility is used to detect if the ports are in TE or NT mode and
setup dahdi-channels.conf appropriately.

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

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10256 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-21 22:12:49 +00:00
Shaun Ruffell
e9ea988620 dahdi_genconf: Assume spans with unknown term types are software selectable.
Resolves a regression on the 2.5 branch that would result in:

  $ dahdi_genconf
  dahdi_genconf: missing default group (termtype=UNKNOWN)

E1 / T1 spans use software configuration to set CPE / NET mode. This
patch will just assume that a termtype is software selectable if it was
"UNKNOWN" when first scanning the span.

Internal-Issue-ID: DAHTOOL-55
Signed-off-by: Shaun Ruffell <sruffell@digium.com>
Tested-by: David Purdue <support@noojee.com.au>

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10255 17933a7a-c749-41c5-a318-cba88f637d49
2011-10-21 22:12:45 +00:00
Tzafrir Cohen
0245fef736 xpp: waitfor_xpds: higher and configurable timeout
On several pathological cases we may need to wait more than 40 seconds.
Make that timeout configurable.

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10188 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-07 07:11:14 +00:00
Tzafrir Cohen
e8c7b0042e README.Astribank: HWEC and build instructions
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10187 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-07 07:10:53 +00:00
Tzafrir Cohen
ff04c5db31 xpp: pri_termtype: match complete SPAN patterns
Match complete span patterns, to avoid pattern 'SPAN/1' from matching
e.g. span 12 (SPAN/12).

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

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10186 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-07 07:10:28 +00:00
Tzafrir Cohen
b3824291d5 Extra README fixes: 'th' and ztcfg
Signed-off-by: Tzafrir Cohen <tzafrir.cohen@xorcom.com>

git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10185 17933a7a-c749-41c5-a318-cba88f637d49
2011-09-07 07:09:47 +00:00
Tzafrir Cohen
58afc8f173 Create a branch for 2.5
git-svn-id: http://svn.astersk.org/svn/dahdi/tools/branches/2.5@10108 17933a7a-c749-41c5-a318-cba88f637d49
2011-08-10 17:22:00 +00:00
33 changed files with 2992 additions and 624 deletions

1
.version Normal file
View File

@@ -0,0 +1 @@
2.5.1-rc1

1855
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

4
README
View File

@@ -66,7 +66,7 @@ Installation to a Subtree
^^^^^^^^^^^^^^^^^^^^^^^^^
The following may be useful when testing the package or when preparing a
package for a binary distribution (such as an rpm package) installing
onto a subtree rather than on th real system.
onto a subtree rather than on the real system.
make install DESTDIR=targetdir
@@ -138,7 +138,7 @@ include::genconf_parameters.asciidoc[]
Tonezones
~~~~~~~~~
The file zonedata.c contains the information about the tone zones used
in libtonezone (and hence also in ztcfg). Here is a list of those zones:
in libtonezone (and hence also in dahdi_cfg). Here is a list of those zones:
include::tonezones.txt[]

View File

@@ -258,11 +258,10 @@ static int parseargs(char *input, char *output[], int maxargs, char sep)
int dspanconfig(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int chans;
int timing;
argc = res = parseargs(args, realargs, 4, ',');
res = parseargs(args, realargs, 4, ',');
if (res != 4) {
error("Incorrect number of arguments to 'dynamic' (should be <driver>,<address>,<num channels>, <timing>)\n");
return -1;
@@ -755,13 +754,12 @@ static int unimplemented(char *keyword, char *args)
int ctcss(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int rxtone;
int rxtag;
int txtone;
int isdcs = 0;
argc = res = parseargs(args, realargs, 3, ',');
res = parseargs(args, realargs, 3, ',');
if (res != 3) {
error("Incorrect number of arguments to 'ctcss' (should be <rxtone>,<rxtag>,<txtone>)\n");
return -1;
@@ -808,10 +806,9 @@ int ctcss(char *keyword, char *args)
int dcsrx(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int rxtone;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'dcsrx' (should be <rxtone>)\n");
return -1;
@@ -831,11 +828,10 @@ int dcsrx(char *keyword, char *args)
int tx(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int txtone;
int isdcs = 0;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'tx' (should be <txtone>)\n");
return -1;
@@ -860,10 +856,9 @@ int tx(char *keyword, char *args)
int debounce_time(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'debouncetime' (should be <value>)\n");
return -1;
@@ -883,10 +878,9 @@ int debounce_time(char *keyword, char *args)
int burst_time(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'bursttime' (should be <value>)\n");
return -1;
@@ -906,10 +900,9 @@ int burst_time(char *keyword, char *args)
int tx_gain(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'txgain' (should be <value>)\n");
return -1;
@@ -927,10 +920,9 @@ int tx_gain(char *keyword, char *args)
int rx_gain(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'rxgain' (should be <value>)\n");
return -1;
@@ -948,10 +940,9 @@ int rx_gain(char *keyword, char *args)
int de_emp(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'de-emp' (should be <value>)\n");
return -1;
@@ -971,10 +962,9 @@ int de_emp(char *keyword, char *args)
int pre_emp(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'pre_emp' (should be <value>)\n");
return -1;
@@ -994,10 +984,9 @@ int pre_emp(char *keyword, char *args)
int invert_cor(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'invertcor' (should be <value>)\n");
return -1;
@@ -1021,10 +1010,9 @@ int invert_cor(char *keyword, char *args)
int ext_tone(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'exttone' (should be <value>)\n");
return -1;
@@ -1050,11 +1038,10 @@ int ext_tone(char *keyword, char *args)
int cor_thresh(char *keyword, char *args)
{
static char *realargs[10];
int argc;
int res;
int val;
int x = 0;
argc = res = parseargs(args, realargs, 1, ',');
res = parseargs(args, realargs, 1, ',');
if (res != 1) {
error("Incorrect number of arguments to 'corthresh' (should be <value>)\n");
return -1;

View File

@@ -79,7 +79,6 @@ int main(int argc, char *argv[])
int doloopback = 0;
char *larg = NULL;
int sflag = 0;
int span = 1;
int iflag = 0;
char *iarg = NULL;
@@ -116,7 +115,6 @@ int main(int argc, char *argv[])
break;
case 's': /* specify a span */
span = atoi(optarg);
sflag = 1;
break;
case 'i': /* insert an error */
iarg = optarg;

View File

@@ -74,7 +74,7 @@ ASTRIBANK_OBJS = astribank_usb.o mpptalk.o $(XTALK_OBJS)
ABHEXLOAD_OBJS = astribank_hexload.o hexfile.o pic_loader.o $(ECHO_LOADER) $(ASTRIBANK_OBJS) $(OCT_HERE_OBJS)
ABTOOL_OBJS = astribank_tool.o $(ASTRIBANK_OBJS)
ABALLOW_OBJS = astribank_allow.o $(ASTRIBANK_OBJS)
ABALLOW_OBJS = astribank_allow.o astribank_license.o $(ASTRIBANK_OBJS)
TARGETS = .perlcheck astribank_is_starting
PROG_INSTALL = astribank_is_starting

View File

@@ -43,27 +43,42 @@ an FXO module of two ports.
Building and Installation
-------------------------
Apart from the standard DAHDI build requirements, you also need libusb
development headers to build the fpga_load firmware loader. This is
typically the package libusb-dev on Debian (and derivatives like Ubuntu)
or libusb-devel on RedHat (and derivatives like CentOS/Trixbox).
Apart from the standard DAHDI build requirements, you also need:
Patch for BRI
~~~~~~~~~~~~~
(As of DAHDI 2.2 this patch is no longer needed. Furthermore, it does
not apply. The same directory has a newer patch that applies. This
section is kept in the document for the time being for the benefit of
those with older versions)
* *libusb development headers* to build the fpga_load firmware loader.
This is typically the package libusb-dev on Debian (and derivatives
like Ubuntu) or libusb-devel on RedHat (and derivatives like
CentOS/Trixbox).
* *Echo Canceller Module firmware*: If you have an Astribank with an
echo canceller module, see the following section.
In order for the BRI module (xpd_bri.ko) to build, you still need an
external patch:
Follow the build instructions of DAHDI-linux and DAHDI-tools. But
Basically, in dahdi-linux run:
http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff[]
make
make install # as root
You need to apply it to the dahdi-linux tarball before building:
And later in dahdi-tools:
wget http://updates.xorcom.com/astribank/bristuff/dahdi_bri_dchan.diff
patch -p1 <dahdi_bri_dchan.diff
./configure
make
make install # as root
Echo Canceller Firmware
~~~~~~~~~~~~~~~~~~~~~~~
If you install from source, you should copy OCT6104E-256D.ima to the
source tree (before running make install:
wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima
mv OCT6104E-256D.ima drivers/dahdi/xpp/firmwares/
Alternatively, if you have already installed DAHDI-linux (e.g. from a
binary package that does not include the firmware) you can just copy
it directly to the target directory, /usr/share/dahdi using:
cd /usr/share/dahdi
wget http://updates.xorcom.com/astribank/hwec/OCT6104E-256D.ima
Installation Scenarios

View File

@@ -48,6 +48,16 @@ Write capabilities to EEPROM, otherwise read capabilities
License filename (stdin/stdout if not specified)
.RE
.B \-m \fInum\fR
.RS
Choose the numeric code of license markers to generate.
This code select the type of \fIBEGIN\fR.../\fIEND\fR... strings
that delimit the license body.
Valid marker codes are listed with the \fB-h\fR option.
The default (and first) code is \fB1\fR. Zero is illegal value.
.RE
.B \-v
.RS
Increase verbosity. May be used multiple times.

View File

@@ -34,6 +34,7 @@
#include "mpp.h"
#include "mpptalk.h"
#include <debug.h>
#include "astribank_license.h"
static const char rcsid[] = "$Id$";
@@ -49,6 +50,8 @@ static void usage()
fprintf(stderr, "\t\t[-d mask] # Debug mask (0xFF for everything)\n");
fprintf(stderr, "\t\t[-w] # Write capabilities to EEPROM, otherwise read capabilities\n");
fprintf(stderr, "\t\t[-f filename] # License filename (stdin/stdout if not specified)\n\n");
fprintf(stderr, "\t\t[-m num] # Numeric code of License markers to generate\n");
license_markers_help("\t", stderr);
exit(1);
}
@@ -70,216 +73,6 @@ static int capabilities_burn(
return 0;
}
static int bin_to_file(void *buf, int len, FILE *f)
{
static int bytes_on_line;
unsigned char *p = buf;
if (buf == NULL) {
if (bytes_on_line != 0) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
return 0;
}
int i;
for (i = 0; i < len; i++) {
if (fprintf(f, "%02x", *p++) != 2)
return -1;
bytes_on_line++;
if (bytes_on_line >= 16) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
}
return 0;
}
static int write_to_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *key, FILE *f)
{
fprintf(f, "-----BEGIN XORCOM LICENSE BLOCK-----\n");
fprintf(f, "Version: 1.0\n");
fprintf(f, "Timestamp: %u\n", caps->timestamp);
fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label);
fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs);
fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo);
fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri);
fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri);
fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo);
fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps));
fprintf(f, "Data:\n");
bin_to_file(eeprom_table, sizeof(*eeprom_table), f);
bin_to_file(caps, sizeof(*caps), f);
bin_to_file(key, sizeof(*key), f);
bin_to_file(NULL, 0, f);
fprintf(f, "-----END XORCOM LICENSE BLOCK-----\n");
return 0;
}
/*
* Removes whitespace on both sizes of the string.
* Returns a pointer to the first non-space char. The string
* is modified in place to trim trailing whitespace.
* If the whole string is whitespace, returns NULL.
*/
char *trim(char *s)
{
int len = strlen(s);
while (len > 0 && isspace(s[len-1])) {
len--;
}
if (len == 0)
return NULL;
s[len] = '\0';
while (isspace(*s))
s++;
/* *s is not a space, since in this case we'd return NULL above */
return s;
}
int get_key_value(char *line, char **key, char **value)
{
char *p = strchr(line, ':');
if (p == NULL)
return -1;
*p = '\0';
*key = trim(line);
*value = trim(p + 1);
return 0;
}
static int hex_digit_to_int(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
static int str_to_bin(char *line, void *buf, int maxlen)
{
static int offset;
unsigned char *p = buf;
if (strlen(line) % 2 != 0)
return -1;
while (offset < maxlen && *line) {
uint8_t value;
char c = hex_digit_to_int(*line++);
if (c < 0 || *line == '\0')
return -1;
value = c << 4;
c = hex_digit_to_int(*line++);
if (c < 0)
return -1;
value |= c;
p[offset++] = value;
}
if (offset == maxlen && *line)
return -1;
return offset;
}
static int read_from_file(struct eeprom_table *eeprom_table, struct capabilities *caps, struct capkey *capkey, FILE *f)
{
char buf[256];
char *line, *key, *value;
int state = 0;
int lineno = 0;
struct table {
struct eeprom_table eeprom_table;
struct capabilities capabilities;
struct capkey capkey;
} PACKED table;
memset(&table, 0, sizeof(struct table));
/*
* states:
* 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1.
* 1: read Version, goto 2. if not version line then error.
* 2: after BEGIN line. split line into key:value. if line is Data:, goto 3.
* 3: read binary data. if line is END_LICENSE_BLOCK goto 4.
* 4: END_LICENSE_BLOCK - ignore lines.
*/
while (fgets(buf, 256, f) != NULL) {
lineno++;
int len = strlen(buf);
if (len > 0 && buf[len-1] != '\n') {
ERR("Line %d: Line too long\n", lineno);
return -1;
}
line = trim(buf);
if (line == NULL) {
if (state > 0 && state < 4) {
ERR("Line %d: Empty line\n", lineno);
return -1;
}
else
continue;
}
switch (state) {
case 0:
if (strcmp(line, "-----BEGIN XORCOM LICENSE BLOCK-----") == 0)
state = 1;
else {
ERR("Line %d: Invalid license begin block\n", lineno);
return -1;
}
break;
case 1:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Version") == 0) {
if (strcmp(value, "1.0") == 0) {
state = 2;
} else {
ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value);
return -1;
}
} else {
ERR("Line %d: No license file version\n", lineno);
return -1;
}
break;
case 2:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Data") == 0) {
state = 3;
break;
}
break;
case 3:
if (strcmp(line, "-----END XORCOM LICENSE BLOCK-----") == 0) {
state = 4;
break;
}
if (str_to_bin(line, &table, sizeof(table)) < 0) {
ERR("Line %d: Error in data block\n", lineno);
return -1;
}
break;
case 4:
break;
}
}
if (state != 4) {
ERR("Invalid license file\n");
return -1;
}
memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table));
memcpy(caps, &table.capabilities, sizeof(*caps));
memcpy(capkey, &table.capkey, sizeof(*capkey));
return 0;
}
int main(int argc, char *argv[])
{
char *devpath = NULL;
@@ -287,8 +80,9 @@ int main(int argc, char *argv[])
struct eeprom_table eeprom_table;
struct capabilities caps;
struct capkey key;
const char options[] = "vd:D:wf:";
const char options[] = "vd:D:wf:m:";
int do_write = 0;
unsigned int marker = LICENSE_MARKER_GENERIC;
FILE *file;
char *filename = NULL;
int ret;
@@ -317,6 +111,11 @@ int main(int argc, char *argv[])
case 'f':
filename = optarg;
break;
case 'm':
marker = strtoul(optarg, NULL, 0);
if (!license_marker_valid(marker))
usage();
break;
case 'h':
default:
ERR("Unknown option '%c'\n", c);
@@ -343,6 +142,7 @@ int main(int argc, char *argv[])
return 1;
}
if (do_write) {
unsigned int used_marker;
/* update capabilities based on input file */
file = stdin;
if (filename) {
@@ -352,7 +152,7 @@ int main(int argc, char *argv[])
return 1;
}
}
ret = read_from_file(&eeprom_table, &caps, &key, file);
ret = read_from_file(&eeprom_table, &caps, &key, &used_marker, file);
if (ret < 0) {
ERR("Failed to read capabilities from file: %d\n", ret);
return 1;
@@ -372,7 +172,7 @@ int main(int argc, char *argv[])
return 1;
}
}
ret = write_to_file(&eeprom_table, &caps, &key, file);
ret = write_to_file(&eeprom_table, &caps, &key, marker, file);
if (ret < 0) {
ERR("Failed to write capabilities to file: %d\n", ret);
return 1;

View File

@@ -1,19 +1,19 @@
.TH "ASTRIBANK_HEXLOAD" "8" "30 May 2011" "" ""
.SH NAME
astribank_tool \- Xorcom Astribank (xpp) firmware loader
astribank_hexload \- Xorcom Astribank (xpp) firmware loader
.SH SYNOPSIS
.B astribank_tool \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-F [\fIoptions\fR] \fIhexfile\fR
.B astribank_tool \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR
.B astribank_hexload \-D \fIdevice-path\fR \-p [\fIoptions\fR] \fIhexfile1 .. hexfile4\fR
.B astribank_tool \-D \fIdevice-path\fR \-O [-A] [\fIoptions\fR] \fIimagefile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-O [-A] [\fIoptions\fR] \fIimagefile\fR
.B astribank_tool \-D \fIdevice-path\fR \-o [\fIoptions\fR]
.B astribank_hexload \-D \fIdevice-path\fR \-o [\fIoptions\fR]
.B astribank_tool \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR
.B astribank_hexload \-D \fIdevice-path\fR \-E [\fIoptions\fR] \fIhexfile\fR
.B astribank_tool \-h
.B astribank_hexload \-h
.SH DESCRIPTION
.B astribank_hexload

View File

@@ -24,6 +24,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <arpa/inet.h>
@@ -36,7 +37,7 @@
#include "../autoconfig.h"
#define DBG_MASK 0x80
#define MAX_HEX_LINES 10000
#define MAX_HEX_LINES 64000
#define HAVE_OCTASIC 1
static char *progname;
@@ -81,15 +82,27 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline)
return 0;
}
void print_parse_errors(int level, const char *msg, ...)
{
va_list ap;
if (verbose > level) {
va_start (ap, msg);
vfprintf (stderr, msg, ap);
va_end (ap);
}
}
static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest)
{
struct hexdata *hexdata = NULL;
int finished = 0;
int ret;
int i;
unsigned i;
char star[] = "+\\+|+/+-";
const char *devstr;
parse_hexfile_set_reporting(print_parse_errors);
if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) {
perror(hexfile);
return -errno;
@@ -100,13 +113,6 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile,
xusb_serial(astribank->xusb),
dev_dest2str(dest),
hexdata->fname, hexdata->version_info);
#if 0
FILE *fp;
if((fp = fopen("fpga_dump_new.txt", "w")) == NULL) {
perror("dump");
exit(1);
}
#endif
if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) {
ERR("%s: Failed hexfile send start: %d\n", devstr, ret);
return ret;

View File

@@ -68,7 +68,34 @@ NUM_WANTED=`clean_lines | sed '/^$/d' | wc -l`
NUM_GOOD=`matched_devices | wc -l`
LOCK="/var/lock/twinstar_startup"
# Wait until udev finished processing our requests
# so we know the device files were actually created
# before trying dahdi_cfg et-al.
wait_for_udev() {
UDEV_SETTLE_MAX_TIME=10
echo "Waiting for udev to settle down..."
if [ -x /sbin/udevsettle ]; then
# Old system, stand-alone udevsettle command
time /sbin/udevsettle --timeout="$UDEV_SETTLE_MAX_TIME"
elif [ -x /sbin/udevadm ]; then
# Assume modern system, udevadm has settle parameter
if ! time /sbin/udevadm settle --timeout="$UDEV_SETTLE_MAX_TIME"
then
echo "udevadm failed ($?)."
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
sleep "$UDEV_SETTLE_MAX_TIME"
fi
else
echo "No udevsettle/udevadm."
echo "Fallback to sleep $UDEV_SETTLE_MAX_TIME seconds."
sleep "$UDEV_SETTLE_MAX_TIME"
fi
sleep 1 # Wait a bit more (races)
}
start_dahdi() {
wait_for_udev
script=/etc/init.d/dahdi
echo "Starting $script."
"$script" start | logger -i -t "$script"

340
xpp/astribank_license.c Normal file
View File

@@ -0,0 +1,340 @@
/*
* Written by Oron Peled <oron@actcom.co.il>
* Copyright (C) 2012, Xorcom
*
* 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 as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <debug.h>
#include "astribank_license.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
static const struct boundary {
const char *name;
const char *markers[2];
} boundaries[] = {
[LICENSE_MARKER_NONE] = { /* Skip 0 */
},
[LICENSE_MARKER_XORCOM] = {
"Xorcom",
{
"-----BEGIN XORCOM LICENSE BLOCK-----",
"-----END XORCOM LICENSE BLOCK-----",
},
},
[LICENSE_MARKER_GENERIC] = {
"Generic",
{
"-----BEGIN TELEPHONY DEVICE LICENSE BLOCK-----",
"-----END TELEPHONY DEVICE LICENSE BLOCK-----",
}
},
};
void license_markers_help(const char *prefix, FILE *fp)
{
int i;
fprintf(fp, "%sValid license markers:\n", prefix);
for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) {
const struct boundary *b = &boundaries[i];
if (b->markers[0] != 0)
fprintf(fp, "%s\t%d - %s\n", prefix, i, b->name);
}
}
int license_marker_valid(unsigned int which)
{
if (which >= ARRAY_SIZE(boundaries))
return 0;
if (boundaries[which].markers[0] == NULL)
return 0;
return 1;
}
static const char *marker_string(unsigned int which, int end_marker)
{
int selector = (end_marker) ? 1 : 0;
if (license_marker_valid(which)) {
return boundaries[which].markers[selector];
}
ERR("gen_marker: invalid marker %d\n", which);
return NULL;
}
static int marker_find(const char *str, int end_marker)
{
int selector = (end_marker) ? 1 : 0;
int i;
for (i = LICENSE_MARKER_NONE + 1; i < ARRAY_SIZE(boundaries); i++) {
const struct boundary *b = &boundaries[i];
const char *marker_str = b->markers[selector];
#if 0
DBG("marker_find(%s,%d)[%d]: %s\n",
str, end_marker, i, marker_str);
#endif
if (!marker_str)
continue;
if (strcmp(str, marker_str) == 0)
return i;
}
return 0;
}
static int bin_to_file(void *buf, int len, FILE *f)
{
static int bytes_on_line;
unsigned char *p = buf;
if (buf == NULL) {
if (bytes_on_line != 0) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
return 0;
}
int i;
for (i = 0; i < len; i++) {
if (fprintf(f, "%02x", *p++) != 2)
return -1;
bytes_on_line++;
if (bytes_on_line >= 16) {
if (fprintf(f, "\n") != 1)
return -1;
bytes_on_line = 0;
}
}
return 0;
}
int write_to_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *key,
unsigned int marker,
FILE *f)
{
fprintf(f, "%s\n", marker_string(marker, 0));
fprintf(f, "Version: 1.0\n");
fprintf(f, "Timestamp: %u\n", caps->timestamp);
fprintf(f, "Serial: %.*s\n", LABEL_SIZE, eeprom_table->label);
fprintf(f, "Capabilities.Port.FXS: %d\n", caps->ports_fxs);
fprintf(f, "Capabilities.Port.FXO: %d\n", caps->ports_fxo);
fprintf(f, "Capabilities.Port.BRI: %d\n", caps->ports_bri);
fprintf(f, "Capabilities.Port.PRI: %d\n", caps->ports_pri);
fprintf(f, "Capabilities.Port.ECHO: %d\n", caps->ports_echo);
fprintf(f, "Capabilities.Twinstar: %d\n", CAP_EXTRA_TWINSTAR(caps));
fprintf(f, "Data:\n");
bin_to_file(eeprom_table, sizeof(*eeprom_table), f);
bin_to_file(caps, sizeof(*caps), f);
bin_to_file(key, sizeof(*key), f);
bin_to_file(NULL, 0, f);
fprintf(f, "%s\n", marker_string(marker, 1));
return 0;
}
/*
* Removes whitespace on both sizes of the string.
* Returns a pointer to the first non-space char. The string
* is modified in place to trim trailing whitespace.
* If the whole string is whitespace, returns NULL.
*/
static char *trim(char *s)
{
int len = strlen(s);
while (len > 0 && isspace(s[len-1])) {
len--;
}
if (len == 0)
return NULL;
s[len] = '\0';
while (isspace(*s))
s++;
/* *s is not a space, since in this case we'd return NULL above */
return s;
}
static int get_key_value(char *line, char **key, char **value)
{
char *p = strchr(line, ':');
if (p == NULL)
return -1;
*p = '\0';
*key = trim(line);
*value = trim(p + 1);
return 0;
}
static int hex_digit_to_int(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
static int str_to_bin(char *line, void *buf, int maxlen)
{
static int offset;
unsigned char *p = buf;
if (strlen(line) % 2 != 0)
return -1;
while (offset < maxlen && *line) {
uint8_t value;
char c = hex_digit_to_int(*line++);
if (c < 0 || *line == '\0')
return -1;
value = c << 4;
c = hex_digit_to_int(*line++);
if (c < 0)
return -1;
value |= c;
p[offset++] = value;
}
if (offset == maxlen && *line)
return -1;
return offset;
}
int read_from_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *capkey,
unsigned int *used_marker,
FILE *f)
{
char buf[256];
char *line, *key, *value;
int lineno = 0;
unsigned int license_marker_begin = 0;
unsigned int license_marker_end;
struct table {
struct eeprom_table eeprom_table;
struct capabilities capabilities;
struct capkey capkey;
} PACKED table;
enum PARSE_STATES {
STATE_BEFORE_LICENSE = 0,
STATE_EXPECT_VERSION = 1,
STATE_EXPECT_DATA = 2,
STATE_READ_DATA = 3,
STATE_AFTER_LICENSE = 4,
} state = STATE_BEFORE_LICENSE;
memset(&table, 0, sizeof(struct table));
/*
* states:
* 0: start - before BEGIN_LICENSE_BLOCK line. on BEGIN_LICENSE_BLOCK line goto 1.
* 1: read Version, goto 2. if not version line then error.
* 2: after BEGIN line. split line into key:value. if line is Data:, goto 3.
* 3: read binary data. if line is END_LICENSE_BLOCK goto 4.
* 4: END_LICENSE_BLOCK - ignore lines.
*/
while (fgets(buf, 256, f) != NULL) {
lineno++;
int len = strlen(buf);
if (len > 0 && buf[len-1] != '\n') {
ERR("Line %d: Line too long\n", lineno);
return -1;
}
line = trim(buf);
if (line == NULL) {
if (state > STATE_BEFORE_LICENSE && state < STATE_AFTER_LICENSE) {
ERR("Line %d: Empty line\n", lineno);
return -1;
}
else
continue;
}
switch (state) {
case STATE_BEFORE_LICENSE:
license_marker_begin = marker_find(line, 0);
if (license_marker_begin)
state = STATE_EXPECT_VERSION;
else {
ERR("Line %d: Invalid license begin block\n", lineno);
return -1;
}
break;
case STATE_EXPECT_VERSION:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Version") == 0) {
if (strcmp(value, "1.0") == 0) {
state = STATE_EXPECT_DATA;
} else {
ERR("Line %d: Unknown license file version '%s', need version '1.0'\n", lineno, value);
return -1;
}
} else {
ERR("Line %d: No license file version\n", lineno);
return -1;
}
break;
case STATE_EXPECT_DATA:
if (get_key_value(line, &key, &value) < 0) {
ERR("Line %d: Can't parse line\n", lineno);
return -1;
}
if (strcmp(key, "Data") == 0) {
state = STATE_READ_DATA;
break;
}
break;
case STATE_READ_DATA:
license_marker_end = marker_find(line, 1);
if (license_marker_end) {
if (license_marker_end != license_marker_begin) {
ERR("Line %d: End marker != Begin marker\n", lineno);
return -1;
}
state = STATE_AFTER_LICENSE;
break;
}
if (str_to_bin(line, &table, sizeof(table)) < 0) {
ERR("Line %d: Error in data block\n", lineno);
return -1;
}
break;
case STATE_AFTER_LICENSE:
break;
}
}
if (state != STATE_AFTER_LICENSE) {
ERR("Invalid license file\n");
return -1;
}
memcpy(eeprom_table, &table.eeprom_table, sizeof(*eeprom_table));
memcpy(caps, &table.capabilities, sizeof(*caps));
memcpy(capkey, &table.capkey, sizeof(*capkey));
return 0;
}

29
xpp/astribank_license.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef ASTRIBANK_ALLOW_H
#define ASTRIBANK_ALLOW_H
#include "mpp.h"
enum license_markers {
LICENSE_MARKER_NONE = 0,
LICENSE_MARKER_XORCOM = 1,
LICENSE_MARKER_GENERIC = 2,
};
int license_marker_valid(unsigned int which);
void license_markers_help(const char *prefix, FILE *fp);
int write_to_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *key,
unsigned int marker,
FILE *f);
int read_from_file(
struct eeprom_table *eeprom_table,
struct capabilities *caps,
struct capkey *capkey,
unsigned int *used_marker,
FILE *f);
#endif /* ASTRIBANK_ALLOW_H */

View File

@@ -64,6 +64,8 @@ static const struct xusb_spec astribank_specs[] = {
TYPE_ENTRY("USB-MULTI", 0x1161, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("FPGA-MULTI", 0x1162, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("BURNED-MULTI", 0x1164, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
TYPE_ENTRY("USB-BURN", 0x1112, 2, 1, 2, MP_EP_OUT, MP_EP_IN),
};
static const struct xusb_spec astribank_pic_specs[] = {

View File

@@ -98,4 +98,16 @@ int eeprom_fill(struct eeprom_table *eprm,
int astribank_has_twinstar(struct astribank_device *astribank);
int label_isvalid(const char *label);
#define AB_REPORT(report_type, astribank, fmt, ...) \
report_type("%s [%s]: " fmt, \
xusb_devpath((astribank)->xusb), \
xusb_serial((astribank)->xusb), \
## __VA_ARGS__)
#define AB_INFO(astribank, fmt, ...) \
AB_REPORT(INFO, astribank, fmt, ## __VA_ARGS__)
#define AB_ERR(astribank, fmt, ...) \
AB_REPORT(ERR, astribank, fmt, ## __VA_ARGS__)
#endif /* ASTRIBANK_USB_H */

View File

@@ -123,9 +123,7 @@ static void usb_buffer_showstatistics(struct astribank_device *astribank, struct
long usec;
usec = usb_buffer_usec(ub);
INFO("%s [%s]: Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%d\n",
xusb_devpath(astribank->xusb),
xusb_serial(astribank->xusb),
AB_INFO(astribank, "Octasic statistics: packet_size=[%d, %ld, %d] packets=%d, bytes=%ld msec=%ld usec/packet=%ld\n",
ub->min_send,
ub->total_bytes / ub->num_sends,
ub->max_send,
@@ -144,7 +142,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe
return 0;
ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT);
if(ret < 0) {
ERR("xusb_send failed: %d\n", ret);
AB_ERR(astribank, "xusb_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
@@ -179,7 +177,7 @@ static int usb_buffer_append(struct astribank_device *astribank, struct usb_buff
char *buf, int len)
{
if (ub->curr + len >= ub->max_len) {
ERR("%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n",
AB_ERR(astribank, "%s: buffer too small ub->curr=%d, len=%d, ub->max_len=%d\n",
__func__, ub->curr, len, ub->max_len);
return -ENOMEM;
}
@@ -211,13 +209,13 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer
return ret;
ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT);
if(ret <= 0) {
ERR("No USB packs to read: %s\n", strerror(-ret));
AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret));
return -EINVAL;
}
DBG("%s: %d bytes recv\n", __func__, ret);
phead = (struct xpp_packet_header *)buf;
if(phead->header.op != SPI_RCV_XOP && phead->header.op != TST_RCV_XOP) {
ERR("Got unexpected reply OP=0x%02X\n", phead->header.op);
AB_ERR(astribank, "Got unexpected reply OP=0x%02X\n", phead->header.op);
dump_packet(LOG_ERR, DBG_MASK, "hexline[ERR]", buf, ret);
return -EINVAL;
}
@@ -260,7 +258,7 @@ int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, i
ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, recv_answer);
if(ret < 0) {
ERR("usb_buffer_send failed: %d\n", ret);
AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
@@ -287,15 +285,16 @@ int test_send(struct astribank_device *astribank)
ret = usb_buffer_send(astribank, &usb_buffer, buf, pack_len, TIMEOUT, 1);
if(ret < 0) {
ERR("usb_buffer_send failed: %d\n", ret);
AB_ERR(astribank, "usb_buffer_send failed: %d\n", ret);
return ret;
}
DBG("%s: Written %d bytes\n", __func__, ret);
return ret;
}
void echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data)
int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data)
{
int ret;
/* DBG("SEND: %04X -> [%04X]\n", data, addr);
DBG("\t\t[%04X] <- %04X\n", 0x0008, (addr >> 20));
DBG("\t\t[%04X] <- %04X\n", 0x000A, (addr >> 4) & ((1 << 16) - 1));
@@ -304,25 +303,48 @@ void echo_send_data(struct astribank_device *astribank, const unsigned int addr,
*/
DBG("SND:\n");
spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
spi_send(astribank, 0x0004, data , 0, 0);
spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0004, data , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
(1 << 8) | (3 << 12) | 1 , 0, 0);
if (ret < 0)
goto failed;
return cOCT6100_ERR_OK;
failed:
AB_ERR(astribank, "echo_send_data: spi_send failed (ret = %d)\n", ret);
return ret;
}
unsigned int echo_recv_data(struct astribank_device *astribank, const unsigned int addr)
int echo_recv_data(struct astribank_device *astribank, const unsigned int addr)
{
unsigned int data = 0x00;
unsigned int ret;
int ret;
DBG("RCV:\n");
spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
ret = spi_send(astribank, 0x0008, (addr >> 20) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x000A, (addr >> 4) & ((1 << 16) - 1) , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0000, (((addr >> 1) & 0x7) << 9) |
(1 << 8) | 1 , 0, 0);
if (ret < 0)
goto failed;
ret = spi_send(astribank, 0x0004, data , 1, 0);
if (ret < 0)
goto failed;
return ret;
failed:
AB_ERR(astribank, "echo_recv_data: spi_send failed (ret = %d)\n", ret);
return ret;
}
int load_file(char *filename, unsigned char **ppBuf, UINT32 *pLen)
@@ -418,9 +440,13 @@ UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams)
const unsigned int data = f_pWriteParams->usWriteData;
const struct echo_mod *echo_mod = (struct echo_mod *)(f_pWriteParams->pProcessContext);
struct astribank_device *astribank = echo_mod->astribank;
int ret;
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
return cOCT6100_ERR_OK;
}
@@ -434,9 +460,15 @@ UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParam
unsigned int i;
for (i = 0; i < len; i++) {
int ret;
addr = f_pSmearParams->ulWriteAddress + (i << 1);
data = f_pSmearParams->usWriteData;
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
}
return cOCT6100_ERR_OK;
}
@@ -451,9 +483,15 @@ UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParam
unsigned int i;
for (i = 0; i < len; i++) {
int ret;
addr = f_pBurstParams->ulWriteAddress + (i << 1);
data = f_pBurstParams->pusWriteData[i];
echo_send_data(astribank, addr, data);
ret = echo_send_data(astribank, addr, data);
if (ret < 0) {
ERR("echo_send_data failed (ret = %d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_WRITE_API;
}
}
return cOCT6100_ERR_OK;
}
@@ -463,8 +501,14 @@ UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams)
const unsigned int addr = f_pReadParams->ulReadAddress;
const struct echo_mod *echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext;
struct astribank_device *astribank = echo_mod->astribank;
int ret;
*f_pReadParams->pusReadData = echo_recv_data(astribank, addr);
ret = echo_recv_data(astribank, addr);
if (ret < 0) {
ERR("echo_recv_data failed (%d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_READ_API;
}
*f_pReadParams->pusReadData = ret;
return cOCT6100_ERR_OK;
}
@@ -477,8 +521,15 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
unsigned int i;
for (i = 0;i < len; i++) {
unsigned int ret;
addr = f_pBurstParams->ulReadAddress + (i << 1);
f_pBurstParams->pusReadData[i] = echo_recv_data(astribank, addr);
ret = echo_recv_data(astribank, addr);
if (ret < 0) {
ERR("echo_recv_data failed (%d)\n", ret);
return cOCT6100_ERR_FATAL_DRIVER_READ_API;
}
f_pBurstParams->pusReadData[i] = ret;
}
return cOCT6100_ERR_OK;
}
@@ -486,7 +537,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams)
inline int get_ver(struct astribank_device *astribank)
{
return spi_send(astribank, 0, 0, 1, 1);
return spi_send(astribank, 0, 0, 1, 1);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -511,18 +562,16 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
tOCT6100_CHANNEL_OPEN ChannelOpen;
UINT32 ulChanHndl;
test_send(astribank);
if (test_send(astribank) < 0)
return cOCT6100_ERR_FATAL;
cpld_ver = get_ver(astribank);
INFO("%s [%s]: Check EC_CPLD version: %d\n",
xusb_devpath(astribank->xusb),
xusb_serial(astribank->xusb),
cpld_ver);
AB_INFO(astribank, "Check EC_CPLD version: %d\n", cpld_ver);
if (cpld_ver < 0)
return cpld_ver;
return cOCT6100_ERR_FATAL;
else if (cpld_ver == EC_VER_TEST) {
INFO("+---------------------------------------------------------+\n");
INFO("| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n");
INFO("+---------------------------------------------------------+\n");
AB_INFO(astribank, "+---------------------------------------------------------+\n");
AB_INFO(astribank, "| WARNING: TEST HARDWARE IS ON THE BOARD INSTEAD OF EC!!! |\n");
AB_INFO(astribank, "+---------------------------------------------------------+\n");
return cOCT6100_ERR_OK;
}
@@ -537,10 +586,10 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
memset(&OpenChip, 0, sizeof(tOCT6100_CHIP_OPEN));
if (!(echo_mod = malloc(sizeof(struct echo_mod)))) {
ERR("cannot allocate memory for echo_mod\n");
return 1;
AB_ERR(astribank, "cannot allocate memory for echo_mod\n");
return cOCT6100_ERR_FATAL;
}
DBG("allocated mem for echo_mod\n");
DBG("allocated mem for echo_mod\n");
memset(echo_mod, 0, sizeof(struct echo_mod));
@@ -548,7 +597,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChipOpenDef( &OpenChip );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Oct6100ChipOpenDef failed: result=%X\n", ulResult);
AB_ERR(astribank, "Oct6100ChipOpenDef failed: result=%X\n", ulResult);
return ulResult;
}
@@ -593,14 +642,14 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
&pbyImageData,
&ulImageByteSize );
if (pbyImageData == NULL || ulImageByteSize == 0){
ERR("Bad pbyImageData or ulImageByteSize\n");
return 1;
}
if ( ulResult != 0 ) {
ERR("Failed load_file %s (%08X)\n", filename, ulResult);
AB_ERR(astribank, "Failed load_file %s (%08X)\n", filename, ulResult);
return ulResult;
}
if (pbyImageData == NULL || ulImageByteSize == 0){
AB_ERR(astribank, "Bad pbyImageData or ulImageByteSize\n");
return cOCT6100_ERR_FATAL;
}
/* Assign the image file.*/
OpenChip.pbyImageFile = pbyImageData;
@@ -613,7 +662,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100GetInstanceSize(&OpenChip, &InstanceSize );
if (ulResult != cOCT6100_ERR_OK)
{
ERR("Oct6100GetInstanceSize failed (%08X)\n", ulResult);
AB_ERR(astribank, "Oct6100GetInstanceSize failed (%08X)\n", ulResult);
return ulResult;
}
@@ -622,14 +671,14 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
echo_mod->astribank = astribank;
if (!pApiInstance) {
ERR("Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
return 1;
AB_ERR(astribank, "Out of memory (can't allocate %d bytes)!\n", InstanceSize.ulApiInstanceSize);
return cOCT6100_ERR_FATAL;
}
/* Perform actual open of chip */
ulResult = Oct6100ChipOpen(pApiInstance, &OpenChip);
if (ulResult != cOCT6100_ERR_OK) {
ERR("Oct6100ChipOpen failed: result=%X\n", ulResult);
AB_ERR(astribank, "Oct6100ChipOpen failed: result=%X\n", ulResult);
return ulResult;
}
DBG("%s: OCT6100 is open\n", __func__);
@@ -687,7 +736,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChannelOpen( pApiInstance,
&ChannelOpen );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Found error on chan %d\n", nChan);
AB_ERR(astribank, "Found error on chan %d\n", nChan);
return ulResult;
}
}
@@ -736,7 +785,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
ulResult = Oct6100ChannelOpen( pApiInstance,
&ChannelOpen );
if (ulResult != cOCT6100_ERR_OK) {
ERR("Found error on chan %d\n", nChan);
AB_ERR(astribank, "Found error on chan %d\n", nChan);
return ulResult;
}
}
@@ -752,24 +801,21 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, int is_a
int load_echo(struct astribank_device *astribank, char *filename, int is_alaw)
{
int iLen;
int ret;
unsigned char *pbyFileData = NULL;
const char *devstr;
UINT32 octasic_status;
devstr = xusb_devpath(astribank->xusb);
INFO("%s [%s]: Loading ECHOCAN Firmware: %s (%s)\n",
devstr, xusb_serial(astribank->xusb), filename,
(is_alaw) ? "alaw" : "ulaw");
AB_INFO(astribank, "Loading ECHOCAN Firmware: %s (%s)\n",
filename, (is_alaw) ? "alaw" : "ulaw");
usb_buffer_init(astribank, &usb_buffer);
ret = init_octasic(filename, astribank, is_alaw);
if (ret) {
ERR("ECHO %s burning failed (%08X)\n", filename, ret);
octasic_status = init_octasic(filename, astribank, is_alaw);
if (octasic_status != cOCT6100_ERR_OK) {
AB_ERR(astribank, "ECHO %s burning failed (%08X)\n",
filename, octasic_status);
return -ENODEV;
}
ret = usb_buffer_flush(astribank, &usb_buffer);
if (ret < 0) {
ERR("ECHO %s buffer flush failed (%d)\n", filename, ret);
AB_ERR(astribank, "ECHO %s buffer flush failed (%d)\n", filename, ret);
return -ENODEV;
}
usb_buffer_showstatistics(astribank, &usb_buffer);

View File

@@ -557,7 +557,6 @@ int match_usb_device_identity(const struct usb_config_descriptor *config_desc,
const struct astribank_type *my_usb_device_identify(const char devpath[], struct my_usb_device *mydev)
{
struct usb_device_descriptor *dev_desc;
struct usb_config_descriptor *config_desc;
int i;
@@ -570,7 +569,6 @@ const struct astribank_type *my_usb_device_identify(const char devpath[], struct
ERR("Bailing out\n");
return 0;
}
dev_desc = &mydev->dev->descriptor;
config_desc = mydev->dev->config;
for(i = 0; i < sizeof(astribank_types)/sizeof(astribank_types[0]); i++) {
if(match_usb_device_identity(config_desc, &astribank_types[i])) {
@@ -592,7 +590,6 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const
struct usb_interface *interface;
struct usb_interface_descriptor *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int ret;
int i;
assert(mydev != NULL);
@@ -638,10 +635,10 @@ int my_usb_device_init(const char devpath[], struct my_usb_device *mydev, const
mydev->abtype = abtype;
mydev->my_ep_in = abtype->my_ep_in;
mydev->my_ep_out = abtype->my_ep_out;
ret = get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle);
ret = get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle);
ret = get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle);
ret = get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle);
get_usb_string(mydev->iManufacturer, BUFSIZ, dev_desc->iManufacturer, mydev->handle);
get_usb_string(mydev->iProduct, BUFSIZ, dev_desc->iProduct, mydev->handle);
get_usb_string(mydev->iSerialNumber, BUFSIZ, dev_desc->iSerialNumber, mydev->handle);
get_usb_string(mydev->iInterface, BUFSIZ, iface_desc->iInterface, mydev->handle);
INFO("ID=%04X:%04X Manufacturer=[%s] Product=[%s] SerialNumber=[%s] Interface=[%s]\n",
dev_desc->idVendor,
dev_desc->idProduct,

View File

@@ -83,7 +83,7 @@ struct capkey {
} PACKED;
struct extrainfo {
char text[24];
char text[EXTRAINFO_SIZE];
} PACKED;
struct mpp_header {

View File

@@ -366,7 +366,17 @@ int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info
}
assert(reply->header.op == MPP_EXTRAINFO_GET_REPLY);
if(info) {
int i;
memcpy(info, (void *)&CMD_FIELD(reply, MPP, EXTRAINFO_GET_REPLY, info), sizeof(*info));
/*
* clean non-printing characters
*/
for (i = sizeof(*info) - 1; i >= 0; i--) {
if (info->text[i] != (char)0xFF)
break;
info->text[i] = '\0';
}
}
free_command(reply);
return 0;
@@ -876,7 +886,11 @@ void show_astribank_status(struct astribank_device *astribank, FILE *fp)
void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp)
{
fprintf(fp, "Extrainfo: : %s\n", (const char *)(extrainfo->text));
char buf[EXTRAINFO_SIZE + 1];
memcpy(buf, extrainfo->text, EXTRAINFO_SIZE);
buf[EXTRAINFO_SIZE] = '\0'; /* assure null termination */
fprintf(fp, "Extrainfo: : '%s'\n", buf);
}
int twinstar_show(struct astribank_device *astribank, FILE *fp)

View File

@@ -108,4 +108,6 @@ enum dev_dest {
DEST_EEPROM = 0x02,
};
#define EXTRAINFO_SIZE 24
#endif /* MPPTALK_DEFS_H */

View File

@@ -1500,7 +1500,6 @@ UINT32 Oct6100ApiReserveChannelResources(
IN tPOCT6100_CHANNEL_OPEN f_pChannelOpen,
OUT tPOCT6100_API_ECHO_CHAN_INDEX f_pChanIndexConf )
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_CHANNEL_OPEN_TDM pTdmConfig;
tPOCT6100_CHANNEL_OPEN_CODEC pCodecConfig;
@@ -1526,9 +1525,6 @@ UINT32 Oct6100ApiReserveChannelResources(
BOOL fExtToneChanEntry = FALSE;
BOOL fExtToneTsiEntry = FALSE;
BOOL fExtToneMixerEntry = FALSE;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/* Obtain a local pointer to the configuration structures.*/
pTdmConfig = &f_pChannelOpen->TdmConfig;
@@ -1951,7 +1947,6 @@ UINT32 Oct6100ApiWriteChannelStructs(
UINT32 ulResult;
UINT32 ulDwordAddress;
UINT32 ulDwordData;
BOOL fConversionEnabled = FALSE;
BOOL fProgramAdpcmMem;
UINT32 ulCompType = 0;
UINT32 ulPcmLaw;
@@ -2036,62 +2031,50 @@ UINT32 Oct6100ApiWriteChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_2C_ENCODED:
ulCompType = 0x4;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_3C_ENCODED:
ulCompType = 0x5;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_4C_ENCODED:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_ENCODED:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G726_ENCODED:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_2C_ENCODED:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_3C_ENCODED:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_4C_ENCODED:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
default:
return cOCT6100_ERR_FATAL_D4;
@@ -2182,67 +2165,54 @@ UINT32 Oct6100ApiWriteChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_4_1:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_3_2:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_2_3:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_4_0:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_3_1:
ulCompType = 0xB;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_2_2:
ulCompType = 0x7;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_3_0:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_2_1:
ulCompType = 0x8;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_16KBPS_2_0:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
default:
@@ -3807,10 +3777,8 @@ UINT32 Oct6100ApiCheckChannelModify(
/* Check the TDM config.*/
if ( f_pChannelModify->fTdmConfigModified == TRUE )
{
tPOCT6100_CHANNEL_MODIFY_TDM pModifyTdm;
tPOCT6100_CHANNEL_OPEN_TDM pOpenTdm;
pModifyTdm = &f_pChannelModify->TdmConfig;
pOpenTdm = &f_pTempChanOpen->TdmConfig;
ulResult = Oct6100ApiCheckTdmConfig( f_pApiInstance,
@@ -4706,7 +4674,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
tOCT6100_WRITE_PARAMS WriteParams;
tPOCT6100_API_CHANNEL_CODEC pApiCodecConf;
tPOCT6100_API_CHANNEL_TDM pApiTdmConf;
tPOCT6100_API_CHANNEL_VQE pApiVqeConf;
UINT32 ulResult;
UINT16 usReadData;
@@ -4717,8 +4684,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
UINT32 ulToneConfIndex;
BOOL fClearPlayoutPointers = FALSE;
BOOL fConversionEnabled = FALSE;
/* Obtain local pointer to shared portion of instance. */
@@ -4740,7 +4705,6 @@ UINT32 Oct6100ApiModifyChannelStructs(
/* Obtain local pointer to the configuration structures of the tPOCT6100_API_CHANNEL structure. */
pApiCodecConf = &pChanEntry->CodecConfig;
pApiTdmConf = &pChanEntry->TdmConfig;
pApiVqeConf = &pChanEntry->VqeConfig;
/*=======================================================================*/
/* Init the RIN and SIN TSST index */
@@ -5090,62 +5054,50 @@ UINT32 Oct6100ApiModifyChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_2C_ENCODED:
ulCompType = 0x4;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_3C_ENCODED:
ulCompType = 0x5;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_4C_ENCODED:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_ENCODED:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G726_ENCODED:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_2C_ENCODED:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_3C_ENCODED:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G711_G727_4C_ENCODED:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
default:
@@ -5262,67 +5214,54 @@ UINT32 Oct6100ApiModifyChannelStructs(
break;
case cOCT6100_G726_40KBPS:
ulCompType = 0x3;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_32KBPS:
ulCompType = 0x2;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_24KBPS:
ulCompType = 0x1;
fConversionEnabled = TRUE;
break;
case cOCT6100_G726_16KBPS:
ulCompType = 0x0;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_4_1:
ulCompType = 0xD;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_3_2:
ulCompType = 0xA;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_40KBPS_2_3:
ulCompType = 0x6;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_4_0:
ulCompType = 0xE;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_3_1:
ulCompType = 0xB;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_32KBPS_2_2:
ulCompType = 0x7;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_3_0:
ulCompType = 0xC;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_24KBPS_2_1:
ulCompType = 0x8;
fConversionEnabled = TRUE;
break;
case cOCT6100_G727_16KBPS_2_0:
ulCompType = 0x9;
fConversionEnabled = TRUE;
break;
default:
@@ -8885,7 +8824,6 @@ UINT32 Oct6100ApiWriteVqeNlpMemory(
{
tPOCT6100_API_CHANNEL pChanEntry;
tPOCT6100_SHARED_INFO pSharedInfo;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_BUFFER_PLAYOUT_STOP BufferPlayoutStop;
UINT32 ulResult;
UINT32 ulTempData;
@@ -8899,10 +8837,6 @@ UINT32 Oct6100ApiWriteVqeNlpMemory(
pSharedInfo = f_pApiInstance->pSharedInfo;
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* Obtain a pointer to the new buffer's list entry. */
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex );
@@ -9856,7 +9790,6 @@ UINT32 Oct6100ApiWriteVqeAfMemory(
{
tPOCT6100_API_CHANNEL pChanEntry;
tPOCT6100_SHARED_INFO pSharedInfo;
tOCT6100_WRITE_PARAMS WriteParams;
UINT32 ulResult;
UINT32 ulTempData;
UINT32 ulAfConfigBaseAddress;
@@ -9868,10 +9801,6 @@ UINT32 Oct6100ApiWriteVqeAfMemory(
pSharedInfo = f_pApiInstance->pSharedInfo;
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* Obtain a pointer to the new buffer's list entry. */
mOCT6100_GET_CHANNEL_ENTRY_PNT( pSharedInfo, pChanEntry, f_usChanIndex );
@@ -12338,12 +12267,8 @@ UINT32 Oct6100ApiWriteDebugChanMemory(
IN UINT16 f_usRinRoutTsiIndex,
IN UINT16 f_usSinSoutTsiIndex )
{
tPOCT6100_SHARED_INFO pSharedInfo;
UINT32 ulResult;
/* Obtain pointer to local portion of the instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/*==============================================================================*/
/* Write the VQE configuration of the debug channel. */

View File

@@ -3569,9 +3569,7 @@ UINT32 Oct6100ApiBootSdram(
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
UINT16 usReadData;
UINT16 usWriteData23E;
UINT16 usWriteData230;
UINT32 i;
@@ -3587,11 +3585,6 @@ UINT32 Oct6100ApiBootSdram(
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pusReadData = &usReadData;
usWriteData23E = 0x0000;
usWriteData230 = 0x0000;
@@ -4995,7 +4988,6 @@ UINT32 Oct6100ApiRunEgo(
OUT PUINT32 f_aulEntry )
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
@@ -5008,9 +5000,6 @@ UINT32 Oct6100ApiRunEgo(
/* Get local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
/* Get local pointer to the chip configuration structure. */
pChipConfig = &f_pApiInstance->pSharedInfo->ChipConfig;
/* Set the process context and user chip ID parameters once and for all. */
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
@@ -5210,7 +5199,6 @@ UINT32 Oct6100ApiInitChannels(
tPOCT6100_SHARED_INFO pSharedInfo;
UINT32 i;
UINT32 ulResult;
tOCT6100_WRITE_BURST_PARAMS BurstParams;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT16 usReadData;
@@ -5220,7 +5208,6 @@ UINT32 Oct6100ApiInitChannels(
UINT32 ulFeatureBitOffset;
UINT32 ulFeatureFieldLength;
UINT32 ulMask;
UINT16 ausWriteData[ 4 ];
UINT16 usLoopCount = 0;
UINT16 usWriteData = 0;
UINT16 usMclkRead;
@@ -5235,11 +5222,6 @@ UINT32 Oct6100ApiInitChannels(
WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
BurstParams.pProcessContext = f_pApiInstance->pProcessContext;
BurstParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
BurstParams.pusWriteData = ausWriteData;
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;

View File

@@ -2893,7 +2893,6 @@ UINT32 Oct6100ApiBridgeAddParticipantToChannel(
tPOCT6100_API_CHANNEL pSourceChanEntry;
tPOCT6100_API_CHANNEL pDestinationChanEntry;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pSourceParticipant;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant;
tPOCT6100_SHARED_INFO pSharedInfo;
@@ -2914,7 +2913,6 @@ UINT32 Oct6100ApiBridgeAddParticipantToChannel(
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceParticipant, pSourceChanEntry->usFlexConfParticipantIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex );
@@ -5069,12 +5067,9 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
tPOCT6100_API_MIXER_EVENT pTempEntry;
tPOCT6100_API_MIXER_EVENT pLoadTempEntry;
tPOCT6100_API_MIXER_EVENT pLastEventEntry;
tPOCT6100_API_MIXER_EVENT pLastLoadOrAccumulateEventEntry;
tPOCT6100_API_CHANNEL pSourceChanEntry;
tPOCT6100_API_CHANNEL pDestinationChanEntry;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pSourceParticipant;
tPOCT6100_API_FLEX_CONF_PARTICIPANT pDestinationParticipant;
tPOCT6100_SHARED_INFO pSharedInfo;
@@ -5083,7 +5078,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
UINT32 ulResult;
UINT32 ulLoopCount;
UINT16 usLastLoadEventIndex;
UINT16 usLoadOrAccumulateEventIndex;
UINT16 usTempEventIndex;
UINT16 usPreviousEventIndex;
@@ -5091,7 +5085,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
UINT16 usReadData;
BOOL fLastEvent = FALSE;
BOOL fSoutCopyEvent = FALSE;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
@@ -5107,8 +5100,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceChanEntry, f_usSourceChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pSourceParticipant, pSourceChanEntry->usFlexConfParticipantIndex );
mOCT6100_GET_CHANNEL_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationChanEntry, f_usDestinationChannelIndex );
mOCT6100_GET_FLEX_CONF_PARTICIPANT_ENTRY_PNT( f_pApiInstance->pSharedInfo, pDestinationParticipant, pDestinationChanEntry->usFlexConfParticipantIndex );
@@ -5127,8 +5118,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex );
pLastEventEntry = pLoadEventEntry;
pLastLoadOrAccumulateEventEntry = pLoadEventEntry;
usLastLoadEventIndex = usTempEventIndex;
usLastEventIndex = usTempEventIndex;
while( pTempEntry->usEventType != cOCT6100_MIXER_CONTROL_MEM_SUB_STORE &&
@@ -5224,9 +5213,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
}
}
pLastLoadOrAccumulateEventEntry = pTempEntry;
usLastLoadEventIndex = usTempEventIndex;
/* Go to the next entry into the list. */
usTempEventIndex = pTempEntry->usNextEventPtr;
mOCT6100_GET_MIXER_EVENT_ENTRY_PNT( pSharedInfo, pTempEntry, usTempEventIndex );
@@ -5362,7 +5348,6 @@ UINT32 Oct6100ApiBridgeRemoveParticipantFromChannel(
if ( pTempEntry->usEventType == cOCT6100_MIXER_CONTROL_MEM_COPY )
{
/* No more previous bridges. */
fSoutCopyEvent = TRUE;
}
/* Now modify the previous last Store or Sub-Store or Head-Node event from another bridge/channel. */
@@ -7412,7 +7397,6 @@ UINT32 Oct6100ApiGetPrevLastSubStoreEvent(
IN UINT16 f_usBridgeFirstLoadEventPtr,
OUT PUINT16 f_pusLastSubStoreEventIndex )
{
tPOCT6100_API_CONF_BRIDGE pBridgeEntry;
tPOCT6100_API_MIXER_EVENT pTempMixerEntry;
UINT16 usNextEventPtr;
UINT16 usHeadEventPtr;
@@ -7421,9 +7405,6 @@ UINT32 Oct6100ApiGetPrevLastSubStoreEvent(
UINT16 usCurrentPtr;
UINT32 ulResult = cOCT6100_ERR_OK;
/* Get current entry to obtain the link to the previous entry.*/
mOCT6100_GET_CONF_BRIDGE_ENTRY_PNT( f_pApiInstance->pSharedInfo, pBridgeEntry, f_usBridgeIndex );
/* Since we have flexible bridges, we have to */
/* run down the list and check for the appropriate event. */

View File

@@ -798,7 +798,6 @@ UINT32 Oct6100ApiReadIntrptRegs(
tPOCT6100_API_CHIP_ERROR_STATS pErrorStats;
tPOCT6100_API_INTRPT_MANAGE pIntrptManage;
tOCT6100_READ_PARAMS ReadParams;
tOCT6100_WRITE_PARAMS WriteParams;
UINT32 ulResult;
UINT16 usReadData;
@@ -820,13 +819,6 @@ UINT32 Oct6100ApiReadIntrptRegs(
ReadParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
ReadParams.pusReadData = &usReadData;
/* Set some parameters of write struct. */
WriteParams.pProcessContext = f_pApiInstance->pProcessContext;
WriteParams.ulUserChipId = pSharedInfo->ChipConfig.ulUserChipId;
/* CPU registers. */
if ( (f_ulRegister210h & 0x00001) != 0 )
{
@@ -1296,7 +1288,6 @@ UINT32 Oct6100ApiWriteIeRegs(
{
tPOCT6100_API_INTRPT_MANAGE pIntrptManage;
tOCT6100_WRITE_PARAMS WriteParams;
tOCT6100_READ_PARAMS ReadParams;
UINT32 ulResult;
/* Get some local pointers. */
@@ -1307,12 +1298,6 @@ UINT32 Oct6100ApiWriteIeRegs(
WriteParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
/* Set some parameters of read struct. */
ReadParams.pProcessContext = f_pApiInstance->pProcessContext;
ReadParams.ulUserChipId = f_pApiInstance->pSharedInfo->ChipConfig.ulUserChipId;
/*==================================================================================*/
WriteParams.ulWriteAddress = 0x104;
WriteParams.usWriteData = 0x0000;

View File

@@ -175,12 +175,9 @@ UINT32 Oct6100ApiValidateTsst(
{
tPOCT6100_SHARED_INFO pSharedInfo;
tPOCT6100_API_CHIP_CONFIG pChipConfig;
PUINT32 pulTsstAlloc;
/* Obtain local pointer to shared portion of instance. */
pSharedInfo = f_pApiInstance->pSharedInfo;
mOCT6100_GET_TSST_ALLOC_PNT( f_pApiInstance->pSharedInfo, pulTsstAlloc );
/* Obtain local pointer to chip configuration. */
pChipConfig = &pSharedInfo->ChipConfig;

View File

@@ -84,14 +84,12 @@ $Octasic_Revision: 20 $
{ \
PVOID _pProcessContext; \
UINT32 _ulUserChipId; \
UINT32 _ulWriteAddress; \
UINT16 _usWriteData; \
UINT32 _ulWriteLength; \
\
/* Store the data that is to be passed to the user. */ \
_pProcessContext = SmearParams.pProcessContext; \
_ulUserChipId = SmearParams.ulUserChipId; \
_ulWriteAddress = SmearParams.ulWriteAddress; \
_usWriteData = SmearParams.usWriteData; \
_ulWriteLength = SmearParams.ulWriteLength; \
\

View File

@@ -34,6 +34,7 @@ my %usb_ids = (
'e4e4:1161' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular USB-firmware' },
'e4e4:1162' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-modular FPGA-firmware' },
'e4e4:1163' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-TwinStar monitor' },
'e4e4:1164' => { DRIVER => 'xpp_usb', DESCRIPTION => 'Astribank-EEPROM burner' },
# Sangoma USB FXO:
'10c4:8461' => { DRIVER => 'wanpipe', DESCRIPTION => 'Sangoma WANPIPE USB-FXO Device' },

View File

@@ -131,7 +131,7 @@ my @bri_strings = (
'(?:quad|octo)BRI PCI ISDN Card.* \[(NT|TE)\]',
'octoBRI \[(NT|TE)\] ',
'HFC-S PCI A ISDN.* \[(NT|TE)\] ',
'(B4XXP) \(PCI\) Card', # Does not expose NT/TE type
'(B4XXP) \(PCI\) Card', # Use dahdi_scan to determine TE/NT mode
'(WCBRI)', # has selectable NT/TE modes via dahdi_cfg
);
@@ -177,6 +177,28 @@ sub init_proto($$) {
$self->{TYPE} = "${proto}_$self->{TERMTYPE}";
}
sub get_digital_spantype {
my $span_no = shift;
my @lines = split /\n/, `dahdi_scan`;
my $found_span = 0;
foreach my $line (@lines) {
if (! $found_span) {
if ($line =~ m/\[$span_no\]/) {
$found_span = 1;
}
} else {
if ($line !~ m/^\[/) {
if ($line =~ m/digital-(TE|NT)/ ){
return $1;
}
} else {
$found_span = 0;
}
}
}
die "Cannot determine digital spantype";
}
sub new($$) {
my $pack = shift or die "Wasn't called as a class method\n";
my $proc_file = shift or die "Missing a proc file parameter\n";
@@ -191,10 +213,16 @@ sub new($$) {
$self->{IS_DIGITAL} = 0;
$self->{IS_BRI} = 0;
$self->{IS_PRI} = 0;
$self->{TERMTYPE} = "UNKNOWN";
foreach my $cardtype (@bri_strings) {
if($head =~ m/$cardtype/) {
my $termtype = $1;
$termtype = 'TE' if ( $1 eq 'B4XXP' or $1 eq 'WCBRI' );
if ($1 eq 'B4XXP') {
$termtype = get_digital_spantype($num);
}
if ($1 eq 'WCBRI') {
$termtype = 'TE';
}
$self->{IS_DIGITAL} = 1;
$self->{IS_BRI} = 1;
$self->{TERMTYPE} = $termtype;
@@ -230,6 +258,11 @@ sub new($$) {
last;
}
}
if (($self->is_soft_term_type == 0) and ($self->termtype eq "UNKNOWN")) {
$self->{IS_SOFT_TERM_TYPE} = 1;
}
($self->{NAME}, $self->{DESCRIPTION}) = (split(/\s+/, $head, 4))[2, 3];
$self->{IS_DAHDI_SYNC_MASTER} =
($self->{DESCRIPTION} =~ /\(MASTER\)/) ? 1 : 0;
@@ -368,7 +401,7 @@ SPEC:
#print STDERR "match: $match\n";
foreach my $pattern (@patlist) {
#print STDERR "testmatch: $pattern =~ $match\n";
if($pattern =~ $match) {
if($pattern =~ /^$match$/) {
#print STDERR "MATCH '$pattern' ~ '$match' termtype=$termtype\n";
$match_termtype = $termtype;
last SPEC;

View File

@@ -29,13 +29,53 @@ set -e
# For lab testing
mydir=`dirname $0`
PATH="${mydir}:${PATH}"
XPP_WAIT_AB_TIMEOUT=100
[ -r /etc/dahdi/init.conf ] && . /etc/dahdi/init.conf
ab_list() {
find /sys/devices -name idVendor 2>/dev/null | \
xargs grep -H 'e4e4' 2>/dev/null | \
sed -e 's/idVendor.*/idProduct/' | xargs grep -H '11[3456]' | \
sed 's,/[^/]*$,,' || :
}
ab_serial_nums() {
ab_list | \
sed 's,$,/serial,' | \
xargs grep -H '' 2>/dev/null | \
sed 's,.*/serial:,,' | \
sed 's/^$/NO-SERIAL/' | \
sort -u
}
detected_serial_nums() {
cat /sys/bus/astribanks/devices/*/transport/serial 2> /dev/null | \
sed 's/^$/NO-SERIAL/' | \
sort -u || :
}
calc_union() {
echo "$@" | tr -s ' ' '\n' | sort -u
}
detected_ab_list() {
# Only check /sys info (don't use /proc anymore).
ab=`find /sys/bus/astribanks/devices/xbus-*/ -name waitfor_xpds 2> /dev/null || :`
echo $ab
find /sys/bus/astribanks/devices/*/ -name waitfor_xpds 2> /dev/null || :
}
waitfor_ab_initialization() {
oldab=''
while
if ! ab=`detected_ab_list`; then
exit 1
fi
test "$oldab" != "$ab"
do
oldab="$ab"
cat $ab
#echo -n 1>&2 "_"
done
}
# Any hardware?
@@ -54,10 +94,25 @@ if ! astribank_is_starting; then
exit 0
fi
# Wait for driver and first device
serial_nums=`ab_serial_nums`
# Loop until detected (hopefully) all astribanks and they are initialized
echo -n 1>&2 "Astribanks detection "
tries=40
while [ ! -e "/sys/bus/astribanks/devices/xbus-00" ]
tries="$XPP_WAIT_AB_TIMEOUT"
last_detected=0
while
new_serial_nums=`ab_serial_nums`
detected_serial_nums=`detected_serial_nums`
curr_union=`calc_union $curr_union $serial_nums $new_serial_nums`
num_detected=`detected_ab_list | wc -l`
if [ "$num_detected" != "$last_detected" ]; then
# Visual feedback (number of detected AB so far)
echo -n 1>&2 "[$num_detected]"
last_detected="$num_detected"
waitfor_ab_initialization > /dev/null
fi
# Break only when we have something and it's stable
test "$curr_union" != "$detected_serial_nums" -o "$detected_serial_nums" = ''
do
if [ "$tries" -le 0 ]; then
echo 1>&2 "TIMEOUT"
@@ -66,21 +121,15 @@ do
echo -n 1>&2 "."
sleep 1
: $((tries-=1))
serial_nums="$new_serial_nums"
done
# Finished: Show a nice output
echo ""
cat /sys/bus/astribanks/devices/*/waitfor_xpds 2> /dev/null || :
# Wait for device to stabilize and XPD's to finish initalizations
echo 1>&2 "Astribanks initializing spans"
while
if ! ab=`ab_list`; then
exit 1
fi
test "$oldab" != "$ab"
do
oldab="$ab"
cat $ab
done
if [ "$XPP_HOTPLUG_DAHDI" = yes ]; then
if [ "$CALLED_FROM_ATRIBANK_HOOK" = '' ]; then
# Now we can wait until the hotplug run would remove the semaphore

View File

@@ -56,7 +56,7 @@ else
fi
debug() {
[ "$DEBUG" != "" ] && $LOGGER "$@"
[ "$DEBUG" != "" ] && echo >&2 "$@"
return 0
}
@@ -70,7 +70,6 @@ ASTRIBANK_TOOL=${ASTRIBANK_TOOL:-/usr/sbin/astribank_tool}
XPP_CONFIG="${XPP_CONFIG:-/etc/dahdi/xpp.conf}"
XPP_UDEV_SLEEP_TIME="${XPP_UDEV_SLEEP_TIME:-15}"
USB_FW="${USB_FW:-USB_FW.hex}"
USB_RECOV="${USB_RECOV:-USB_RECOV.hex}"
if [ -r "$DEFAULTS" ]; then
@@ -105,46 +104,168 @@ find_dev() {
run_fxload() {
sleep_if_race
fxload -t fx2 $* 2>&1 1>/dev/null | $LOGGER
fxload -t fx2 $* 2>&1 1>/dev/null
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "fxload failed with status $status"
echo >&2 "fxload failed with status $status"
exit 55
fi
}
list_via_proc() {
cat /proc/bus/usb/devices | egrep '^P:|^T:' | sed \
-e '/^T:/s/ *Spd.*//' \
-e '/^T:/s, *Lev.*Dev#= *,\t,' \
-e '/^T:/s,Bus=,,' \
-e '/^P:/s,[A-Za-z]\+=,,g' \
-e '/^P:/s,\.,,g' | awk -vusb_prefix="$USB_PREFIX" '
/^T:/ {
bus=$2
dev=$3
}
/^P:/ {
vendor=$2
sub("0x", "", vendor);
prod=$3
sub("0x", "", product);
bcd=$4
printf("%4s/%4s/%d\t%s/%03d/%03d\n",
vendor, prod, bcd, usb_prefix, bus, dev);
}
'
}
list_via_sysfs() {
find /sys/bus/usb/devices -maxdepth 1 -mindepth 1 | \
egrep -v '/usb[0-9]|:' | while read dev; do
(
cat "$dev/idVendor"
cat "$dev/idProduct"
cat "$dev/bcdDevice"
echo "$dev" | sed \
-e 's,/sys/bus/usb/devices/,,' \
-e 's,-.*,,'
cat "$dev/devnum"
) | tr -s '\n' '\t'
echo ''
done | awk -vusb_prefix="$USB_PREFIX" '{
printf("%4s/%4s/%d\t%s/%03d/%03d\n",
$1, $2, $3, usb_prefix, $4, $5);
}'
}
list_via_lsusb() {
lsusb -v | awk -vusb_prefix="$USB_PREFIX" '
/^Bus/ {
sub(":", "", $4);
dev = sprintf("%s/%s/%s ", usb_prefix, $2, $4);
}
/idVendor/ {
id_vendor = $2
sub("0x", "", id_vendor);
}
/idProduct/ {
id_product = $2
sub("0x", "", id_product);
}
/bcdDevice/ {
bcd_device = $2
sub("^0*", "", bcd_device);
sub("[.]", "", bcd_device);
printf("%s/%s/%s\t%s\n",
id_vendor, id_product, bcd_device, dev);
}
'
}
list_devs() {
#echo >&2 "list_devs"
if [ "$#" -eq 0 ]; then
if [ -f /proc/bus/usb/devices ]; then
method='via_proc'
elif [ -d /sys/bus/usb/devices ]; then
method='via_sysfs'
else
method='via_lsusb'
fi
elif [ "$#" -eq 1 ]; then
method="$1"
else
echo >&2 "$0: unknown list_devs method='$method'"
exit 1
fi
case "$method" in
via_proc|via_sysfs|via_lsusb)
;;
*)
echo >&2 "$0: unknown list_devs method='$method'"
exit 1
;;
esac
list_$method | grep -v '^0000/0000/' | sort
}
filter_devs() {
id_str="$1"
#echo >&2 "filter_devs($id_str)"
list_devs | awk -vid_str="$id_str" '{ if ($1 ~ id_str) { print } }'
}
usb_firmware_device() {
id_str="$1"
devpath="$2"
case "$id_str" in
e4e4/11[3456]0/101|e4e4/1163/101)
fw="USB_FW.hex"
;;
e4e4/116[03]/201)
fw="USB_FW.201.hex"
;;
e4e4/*)
debug "No USB firmware for device $devpath ($id_str)"
return
;;
*)
return
;;
esac
fw_file="$FIRMWARE_DIR/$fw"
ver=$(awk '/\$Id:/ { print $4 }' $fw_file)
debug "USB Firmware $fw_file (Version=$ver) into $devpath"
run_fxload -D "$devpath" -I "$fw_file" || exit 1
}
run_astribank_hexload() {
debug "Running: $ASTRIBANK_HEXLOAD $*"
$ASTRIBANK_HEXLOAD "$@" | $LOGGER
$ASTRIBANK_HEXLOAD "$@"
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "$ASTRIBANK_HEXLOAD failed with status $status"
echo >&2 "$ASTRIBANK_HEXLOAD failed with status $status"
exit 77
fi
}
run_astribank_tool() {
debug "Running: $ASTRIBANK_TOOL $*"
$ASTRIBANK_TOOL "$@" | $LOGGER
$ASTRIBANK_TOOL "$@"
status=$PIPESTATUS
if [ $status != 0 ]; then
$LOGGER "$ASTRIBANK_TOOL failed with status $status"
echo >&2 "$ASTRIBANK_TOOL failed with status $status"
exit 77
fi
}
load_usb_fw() {
v_id=$1
p_id=$2
fw=$3
devices=`find_dev $v_id $p_id`
for dev in $devices
do
ver=$(awk '/\$Id:/ { print $4 }' $FIRMWARE_DIR/$fw)
debug "USB Firmware $FIRMWARE_DIR/$fw (Version=$ver) into $dev"
run_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1
done
usb_firmware_all_devices() {
devs=`list_devs`
echo "USB firmware"
echo "$devs" | while read id_str devpath
do
usb_firmware_device "$id_str" "$devpath"
done
wait_renumeration $numdevs 'e4e4/11[3456]1/*' "usb_firmware_all_devices"
}
load_fw_device() {
@@ -152,16 +273,18 @@ load_fw_device() {
fw="$2"
debug "FPGA loading $fw into $dev"
run_astribank_hexload -D "$dev" -F "$FIRMWARE_DIR/$fw"
if [ "$fw" = "FPGA_1161.hex" ]; then
case "$fw" in
FPGA_1161*.hex)
echo_file="$FIRMWARE_DIR/OCT6104E-256D.ima"
law=''
law_str='uLaw'
abtool_output=`$ASTRIBANK_TOOL -D "$dev" -Q 2>/dev/null`
card_type=`echo "$abtool_output" | grep '^CARD 4:' | cut -d= -f2 | cut -d. -f1`
if [ "$card_type" = '5' ]; then
abtool_output=`$ASTRIBANK_TOOL -D "$dev" -Q 2>&1`
ec_card_type=`echo "$abtool_output" | grep 'CARD 4' | sed -e 's/.*type=//' -e 's/\..*//'`
caps_num=`echo "$abtool_output" | grep 'ECHO ports' | sed -e 's/.*: *//'`
if [ "$ec_card_type" = '5' ]; then
debug "ECHO burning into $dev: $echo_file"
card_type_first=`echo "$abtool_output" | grep '^CARD 0:' | cut -d= -f2 | cut -d. -f1`
case "$card_type_first" in
card_type=`echo "$abtool_output" | grep 'CARD 0' | sed -e 's/.*type=//' -e 's/\..*//'`
case "$card_type" in
3) law="-A";;
4)
pri_protocol=''
@@ -182,88 +305,116 @@ load_fw_device() {
if [ "$caps_num" != '0' ]; then
run_astribank_hexload -D "$dev" -O $law "$echo_file"
else
$LOGGER "WARNING: ECHO burning was skipped (no capabilities)"
echo "WARNING: ECHO burning was skipped (no capabilities)"
fi
fi
pic_files=`echo "$FIRMWARE_DIR"/PIC_TYPE_[1-4].hex`
debug "PIC burning into $dev: $pic_files"
debug "PIC burning into $dev: begin $pic_files"
run_astribank_hexload -D "$dev" -p $pic_files
debug "PIC burning finished $pic_files"
fi
debug "PIC burning into $dev: end $pic_files"
;;
esac
# Do renumeration!
run_astribank_tool -D "$dev" -n > /dev/null
debug "Reenumeration done."
run_astribank_tool -D "$dev" -n > /dev/null 2>&1
debug "Renumeration of $dev done."
}
#
# Use in manual loading. Parallelize loading
# firmwares to all of our devices
#
firmware_by_id() {
v_id=$1
p_id=$2
fw=$3
devices=`find_dev $v_id $p_id`
childs=""
for dev in $devices
do
(
set -e
fpga_firmware_device() {
id_str="$1"
devpath="$2"
load_fw_device "$dev" "$fw"
id_product=`echo "$id_str" | cut -d/ -f2`
bcd_device=`echo "$id_str" | cut -d/ -f3`
case "$id_str" in
e4e4/1131/101)
fw="FPGA_FXS.hex"
;;
e4e4/11[456]1/101)
fw="FPGA_${id_product}.hex"
;;
e4e4/1161/201)
fw="FPGA_${id_product}.${bcd_device}.hex"
;;
e4e4/*)
debug "No FPGA firmware for device $devpath ($id_str)"
return
;;
*)
return
;;
esac
debug "Loading $fw into $devpath"
load_fw_device "$devpath" "$fw"
sleep_if_race
) &
childs="$childs $!"
sleep 0.4
done
# Wait for specific childs to get their exit status
wait $childs
}
numdevs() {
v_ids="$1"
p_ids="$2"
id_str="$1"
for v in $v_ids
do
(
for p in $p_ids
do
find_dev $v $p
done
)
done | wc -w
#echo >&2 "numdevs($id_str)"
filter_devs "$id_str" | wc -l
}
wait_renumeration() {
num="$1"
v_ids="$2"
p_ids="$3"
num="$1"
id_str="$2"
caller="$3"
iter=10
while
n=`numdevs "$v_ids" "$p_ids"`
[ "$num" -gt "$n" ]
do
echo -n "."
sleep 1
done
echo "Got all $num devices"
prev=0
echo "Waiting renumeration ($caller)"
while
n=`numdevs "$id_str"`
[ "$num" -gt "$n" ]
do
if [ "$prev" -lt "$n" ]; then
echo -n "+"
else
echo -n "."
fi
sleep 1
prev="$n"
debug "wait($iter) (found $n from $num devices) ($caller)"
if ! iter=`expr $iter - 1`; then
echo "Timeout (found $n from $num devices) ($caller)"
break;
fi
done
echo "Got all $num devices ($caller)"
sleep 1 # Let everything settle
}
fpga_firmware_all_devices() {
echo "Loading FPGA firmwares"
devs=`filter_devs 'e4e4/11[3456]1/*'`
n=`echo "$devs" | wc -l`
echo "$devs" | (
while read id_str devpath; do
fpga_firmware_device "$id_str" "$devpath" &
done
sleep 1
echo "Wait for FPGA loading processes"
wait
)
wait_renumeration $numdevs 'e4e4/11[3456]2/*' "fpga_firmware_device"
}
reset_fpga() {
totaldevs=`numdevs e4e4 '11[3456][0123]'`
devices=`find_dev e4e4 '11[3456][12]'`
debug "Reseting devices [$totaldevs devices]"
for dev in $devices
do
debug "Resetting FPGA Firmware on $dev"
sleep_if_race
run_astribank_tool -D "$dev" -r full 2>&1 >/dev/null
done
if [ "$1" = 'wait' ]; then
wait_renumeration $totaldevs e4e4 '11[3456][03]'
fi
devices=`filter_devs 'e4e4/11[3456][124]/*'`
totaldevs=`numdevs 'e4e4/11[3456][124]/*'`
echo >&2 -- "Reseting devices [$totaldevs devices]"
echo "$devices" | grep -v '^$' | while read id_str dev
do
(
debug "Resetting FPGA Firmware on $dev"
sleep_if_race
run_astribank_tool -D "$dev" -r full >/dev/null 2>&1
) &
done
wait
if [ "$1" = 'wait' ]; then
wait_renumeration $totaldevs 'e4e4/11[3456][03]/*' "reset_fpga"
fi
}
usage() {
@@ -304,29 +455,28 @@ reset-wait)
reset)
reset_fpga
;;
list)
filter_devs 'e4e4/*/*'
exit 0
;;
xppdetect|load|usb)
numdevs=`numdevs e4e4 '11[3456][013]'`
$LOGGER -- "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
numdevs=`numdevs 'e4e4/11[3456][0134]/*'`
echo >&2 -- "--------- FIRMWARE LOADING: ($1) [$numdevs devices]"
load_usb_fw e4e4 1130 $USB_FW
load_usb_fw e4e4 1140 $USB_FW
load_usb_fw e4e4 1150 $USB_FW
load_usb_fw e4e4 1160 $USB_FW
load_usb_fw e4e4 1163 $USB_FW
wait_renumeration $numdevs e4e4 '11[3456]1'
usb_firmware_all_devices
if [ "$1" != 'usb' ]
then
firmware_by_id e4e4 1131 FPGA_FXS.hex
firmware_by_id e4e4 1141 FPGA_1141.hex
firmware_by_id e4e4 1151 FPGA_1151.hex
firmware_by_id e4e4 1161 FPGA_1161.hex
wait_renumeration $numdevs e4e4 '11[3456]2'
fpga_firmware_all_devices
fi
sleep 3 # Let it stabilize
$LOGGER -- "--------- FIRMWARE IS LOADED"
echo >&2 -- "--------- FIRMWARE IS LOADED"
exit 0
;;
recover-sb)
# Load a firmware that fixes a but which makes the Source Byte in the
# EEPROM reset and make the device appear like a Cypress dev kit:
load_usb_fw 04b4 8613 $USB_RECOV
;;
help)
usage
exit 0
@@ -374,32 +524,33 @@ udev_delayed_load() {
sleep 1
done
if [ $usb_dev_writable != 1 ]; then
$LOGGER "Device $DEVICE not writable. Can't load firmware."
echo >&2 "Device $DEVICE not writable. Can't load firmware."
return;
fi
$LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE"
prod_id=`echo "$PRODUCT" | cut -d/ -f2`
echo >&2 "Trying to find what to do for product $PRODUCT, device $DEVICE"
case "$PRODUCT" in
e4e4/11[3456]0/*|e4e4/1163/*)
FIRM_USB="$FIRMWARE_DIR/$USB_FW"
$LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'"
4b4/8613/*)
# This case is for a potentially-broken Astribank.
# In most systems you should not set udev rules for those to
# get here, as this is actually the ID of a Cypress dev-kit:
FIRM_USB="$FIRMWARE_DIR/$USB_RECOV"
echo >&2 "Loading recovery firmware '$FIRM_USB' into '$DEVICE'"
run_fxload -D "$DEVICE" -I "$FIRM_USB"
;;
e4e4/11[3456]0/*|e4e4/1163/*)
usb_firmware_device "$PRODUCT" "$DEVICE"
;;
e4e4/11[3456]1/*)
# There are potentially two separate udev events, for
# each of the two endpoints. Ignore the first interface:
case "$DEVPATH" in *.0) exit 0;; esac
if [ "$prod_id" = 1131 ]; then
FIRM_FPGA="FPGA_FXS.hex" # Legacy
else
FIRM_FPGA="FPGA_$prod_id.hex"
fi
sleep_if_race
load_fw_device "$DEVICE" "$FIRM_FPGA"
fpga_firmware_device "$PRODUCT" "$DEVICE" &
wait # parallel firmware loading
;;
esac
}
udev_delayed_load &
udev_delayed_load 2>&1 | $LOGGER &

View File

@@ -243,16 +243,17 @@ static int send_command(struct xtalk_device *xtalk_dev, struct xtalk_command *cm
{
int ret;
int len;
char *buf;
void *priv = xtalk_dev->transport_priv;
len = cmd->header.len;
cmd->header.seq = xtalk_dev->tx_sequenceno;
buf = (char *)cmd;
//printf("%s: len=%d\n", __FUNCTION__, len);
#if 0
extern FILE *fp;
char *buf;
buf = (char *)cmd;
if(fp) {
int i;

View File

@@ -30,11 +30,16 @@
#include <arpa/inet.h>
#include <debug.h>
#include <xusb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
static const char rcsid[] = "$Id$";
#define DBG_MASK 0x01
#define TIMEOUT 500
#define MAX_RETRIES 10
struct xusb {
struct usb_device *dev;
@@ -56,6 +61,8 @@ struct xusb {
size_t packet_size;
};
static void xusb_init();
void xusb_init_spec(struct xusb_spec *spec, char *name,
uint16_t vendor_id, uint16_t product_id,
int nifaces, int iface, int nep, int ep_out, int ep_in)
@@ -363,9 +370,7 @@ struct xusb *xusb_find_iface(const char *devpath, int iface_num, int ep_out, int
struct usb_bus *bus;
DBG("\n");
usb_init();
usb_find_busses();
usb_find_devices();
xusb_init();
for (bus = usb_get_busses(); bus; bus = bus->next) {
int bus_num;
char tmppath[PATH_MAX + 1];
@@ -477,9 +482,7 @@ struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, int numspe
ERR("Failed allocation new xlist");
goto fail_xlist;
}
usb_init();
usb_find_busses();
usb_find_devices();
xusb_init();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *dev_desc;
@@ -540,7 +543,10 @@ struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, xusb_fil
xusb = curr->data;
xlist_destroy(curr, NULL);
xlist_destroy(xusb_list, NULL);
xusb_claim_interface(xusb);
if(!xusb_claim_interface(xusb)) {
xusb_destroy(xusb);
return NULL;
}
xusb_showinfo(xusb);
break;
default:
@@ -657,12 +663,14 @@ int xusb_close(struct xusb *xusb)
int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
{
int ret;
int retries = 0;
dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, buf, len);
if(EP_OUT(xusb) & USB_ENDPOINT_IN) {
ERR("%s called with an input endpoint 0x%x\n", __FUNCTION__, EP_OUT(xusb));
return -EINVAL;
}
retry_write:
ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout);
if(ret < 0) {
/*
@@ -672,17 +680,39 @@ int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
if(ret != -ENODEV) {
ERR("bulk_write to endpoint 0x%x failed: (%d) %s\n",
EP_OUT(xusb), ret, usb_strerror());
dump_packet(LOG_ERR, DBG_MASK, "xbus_send[ERR]", buf, len);
dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len);
//exit(2);
} else {
DBG("bulk_write to endpoint 0x%x got ENODEV\n", EP_OUT(xusb));
xusb_close(xusb);
}
return ret;
} else if(ret != len) {
}
if(!ret) {
#if 0
FILE *fp;
fp = fopen("/tmp/xusb.log", "a");
if (!fp) {
ERR("%s: Failed writing to /tmp/xusb.log\n", __func__);
return -EFAULT;
}
fprintf(fp, "[%ld] bulk_write to endpoint 0x%x short write[%d]: (%d)\n",
time(NULL), EP_OUT(xusb), retries, ret);
fclose(fp);
#endif
ERR("bulk_write to endpoint 0x%x short write[%d]: (%d)\n",
EP_OUT(xusb), retries, ret);
if (retries++ > MAX_RETRIES) {
return -EFAULT;
}
usleep(100);
goto retry_write;
}
if(ret != len) {
ERR("bulk_write to endpoint 0x%x short write: (%d) %s\n",
EP_OUT(xusb), ret, usb_strerror());
dump_packet(LOG_ERR, DBG_MASK, "xbus_send[ERR]", buf, len);
dump_packet(LOG_ERR, DBG_MASK, "xusb_send[ERR]", buf, len);
return -EFAULT;
}
return ret;
@@ -691,11 +721,13 @@ int xusb_send(struct xusb *xusb, char *buf, int len, int timeout)
int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout)
{
int ret;
int retries = 0;
if(EP_IN(xusb) & USB_ENDPOINT_OUT) {
ERR("%s called with an output endpoint 0x%x\n", __FUNCTION__, EP_IN(xusb));
return -EINVAL;
}
retry_read:
ret = usb_bulk_read(xusb->handle, EP_IN(xusb), buf, len, timeout);
if(ret < 0) {
DBG("bulk_read from endpoint 0x%x failed: (%d) %s\n",
@@ -703,6 +735,27 @@ int xusb_recv(struct xusb *xusb, char *buf, size_t len, int timeout)
memset(buf, 0, len);
return ret;
}
if(!ret) {
#if 0
FILE *fp;
fp = fopen("/tmp/xusb.log", "a");
if (!fp) {
ERR("%s: Failed writing to /tmp/xusb.log\n", __func__);
return -EFAULT;
}
fprintf(fp, "[%ld] bulk_read from endpoint 0x%x short read[%d]: (%d)\n",
time(NULL), EP_IN(xusb), retries, ret);
fclose(fp);
#endif
ERR("bulk_read to endpoint 0x%x short read[%d]: (%d)\n",
EP_IN(xusb), retries, ret);
if (retries++ > MAX_RETRIES) {
return -EFAULT;
}
usleep(100);
goto retry_read;
}
dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, buf, ret);
return ret;
}
@@ -724,3 +777,74 @@ int xusb_flushread(struct xusb *xusb)
}
return 0;
}
/*
* Serialize calls to usb_find_busses()/usb_find_devices()
*/
static const key_t SEM_KEY = 0x1a2b3c4d;
static int semid = -1; /* Failure */
static void xusb_lock_usb()
{
struct sembuf sembuf;
while (semid < 0) {
/* Maybe it was already created? */
semid = semget(SEM_KEY, 1, 0);
if (semid < 0) {
/* No, let's create ourselves */
semid = semget(SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0644);
if (semid < 0) {
/* Someone else won the race to create it */
if (errno != ENOENT)
ERR("%s: semget() failed: %s\n",
__func__, strerror(errno));
/* Retry */
continue;
}
/* Initialize */
if (semctl(semid, 0, SETVAL, 1) < 0)
ERR("%s: SETVAL() failed: %s\n",
__func__, strerror(errno));
}
}
DBG("%d: LOCKING\n", getpid());
sembuf.sem_num = 0;
sembuf.sem_op = -1;
sembuf.sem_flg = SEM_UNDO;
if (semop(semid, &sembuf, 1) < 0) {
ERR("%s: semop() failed: %s\n", __func__, strerror(errno));
}
DBG("%d: LOCKED\n", getpid());
}
static void xusb_unlock_usb()
{
struct sembuf sembuf;
DBG("%d: UNLOCKING\n", getpid());
sembuf.sem_num = 0;
sembuf.sem_op = 1;
sembuf.sem_flg = SEM_UNDO;
if (semop(semid, &sembuf, 1) < 0) {
ERR("%s: semop() failed: %s\n", __func__, strerror(errno));
}
DBG("%d: UNLOCKED\n", getpid());
}
static int initizalized = 0;
static void xusb_init()
{
if (!initizalized) {
if (!getenv("XUSB_NOLOCK"))
xusb_lock_usb();
usb_init();
usb_find_busses();
usb_find_devices();
initizalized = 1;
if (!getenv("XUSB_NOLOCK"))
xusb_unlock_usb();
}
}