Compare commits
28 Commits
next
...
v2.5.1-rc1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
396d4580b8 | ||
|
|
9c7a24f901 | ||
|
|
e0c5ee7b0c | ||
|
|
c4fe52e769 | ||
|
|
c57672cd88 | ||
|
|
c256218779 | ||
|
|
261869a437 | ||
|
|
57749f1c26 | ||
|
|
6da1f767e5 | ||
|
|
3a147a35c2 | ||
|
|
a8c8435ea8 | ||
|
|
0124097dfc | ||
|
|
a09b124790 | ||
|
|
c5b905b1bf | ||
|
|
e0485bafc0 | ||
|
|
d6dafbdcea | ||
|
|
d1d22bf4f6 | ||
|
|
cdbea31d0b | ||
|
|
b229de1beb | ||
|
|
04d6bc2893 | ||
|
|
ff25216d3a | ||
|
|
2f10cda05a | ||
|
|
e9ea988620 | ||
|
|
0245fef736 | ||
|
|
e8c7b0042e | ||
|
|
ff04c5db31 | ||
|
|
b3824291d5 | ||
|
|
58afc8f173 |
4
README
4
README
@@ -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[]
|
||||
|
||||
|
||||
39
dahdi_cfg.c
39
dahdi_cfg.c
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
340
xpp/astribank_license.c
Normal 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
29
xpp/astribank_license.h
Normal 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 */
|
||||
@@ -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[] = {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -83,7 +83,7 @@ struct capkey {
|
||||
} PACKED;
|
||||
|
||||
struct extrainfo {
|
||||
char text[24];
|
||||
char text[EXTRAINFO_SIZE];
|
||||
} PACKED;
|
||||
|
||||
struct mpp_header {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -108,4 +108,6 @@ enum dev_dest {
|
||||
DEST_EEPROM = 0x02,
|
||||
};
|
||||
|
||||
#define EXTRAINFO_SIZE 24
|
||||
|
||||
#endif /* MPPTALK_DEFS_H */
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; \
|
||||
\
|
||||
|
||||
@@ -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' },
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
383
xpp/xpp_fxloader
383
xpp/xpp_fxloader
@@ -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 &
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
144
xpp/xtalk/xusb.c
144
xpp/xtalk/xusb.c
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user