From 0e6b068e8902eb6a96017e37b71bbe1a934a105a Mon Sep 17 00:00:00 2001 From: Oron Peled Date: Sun, 21 Dec 2014 14:58:03 -0500 Subject: [PATCH] xpp: migrate everything to libxtalk * Build new libxtalk as local convenience library * Have new mpptalk.[ch] and astribank.[ch] wrap the new API * Modify all tools to use the new API Signed-off-by: Oron Peled Signed-off-by: Tzafrir Cohen --- xpp/Makefile.am | 18 +- xpp/astribank.c | 177 ++++++++ xpp/astribank.h | 33 ++ xpp/astribank_allow.c | 47 +- xpp/astribank_hexload.c | 64 ++- xpp/astribank_license.c | 2 +- xpp/astribank_license.h | 2 +- xpp/astribank_tool.c | 119 +---- xpp/astribank_usb.c | 276 ------------ xpp/astribank_usb.h | 113 ----- xpp/echo_loader.c | 59 +-- xpp/echo_loader.h | 8 +- xpp/mpp.h | 202 --------- xpp/mpptalk.c | 771 +++++++++++++++++++++----------- xpp/mpptalk.h | 194 +++++--- xpp/mpptalk_defs.h | 113 ----- xpp/pic_loader.c | 47 +- xpp/pic_loader.h | 6 +- xpp/xtalk/Makefile.am | 5 - xpp/xtalk/xtalk.c | 497 --------------------- xpp/xtalk/xtalk.h | 178 -------- xpp/xtalk/xtalk_base.c | 5 + xpp/xtalk/xtalk_defs.h | 41 -- xpp/xtalk/xusb.c | 943 --------------------------------------- xpp/xtalk/xusb.h | 102 ----- xpp/xtalk/xusb_libusbx.c | 2 +- 26 files changed, 1007 insertions(+), 3017 deletions(-) create mode 100644 xpp/astribank.c create mode 100644 xpp/astribank.h delete mode 100644 xpp/astribank_usb.c delete mode 100644 xpp/astribank_usb.h delete mode 100644 xpp/mpp.h delete mode 100644 xpp/mpptalk_defs.h delete mode 100644 xpp/xtalk/xtalk.c delete mode 100644 xpp/xtalk/xtalk.h delete mode 100644 xpp/xtalk/xtalk_defs.h delete mode 100644 xpp/xtalk/xusb.c delete mode 100644 xpp/xtalk/xusb.h diff --git a/xpp/Makefile.am b/xpp/Makefile.am index e6fb290..ef203ff 100644 --- a/xpp/Makefile.am +++ b/xpp/Makefile.am @@ -8,7 +8,7 @@ man_MANS = # FIXME: try to improve code, so we can use $(PEDANTIC) #PEDANTIC = -ansi -pedantic -std=c99 -GLOBAL_CFLAGS = -I$(srcdir) -I$(srcdir)/xtalk $(PEDANTIC) +GLOBAL_CFLAGS = -I$(srcdir) -I$(srcdir)/xtalk/include $(PEDANTIC) -Wall if DAHDI_DEVMODE GLOBAL_CFLAGS += \ @@ -81,24 +81,14 @@ endif noinst_LTLIBRARIES = libastribank.la libecholoader.la libhexfile.la libastribank_la_SOURCES = \ - astribank_usb.c \ - astribank_usb.h \ + astribank.c \ + astribank.h \ mpptalk.c \ mpptalk.h \ - mpp.h \ - mpptalk_defs.h \ - xtalk/debug.c \ - xtalk/debug.h \ - xtalk/xlist.c \ - xtalk/xlist.h \ - xtalk/xtalk.c \ - xtalk/xtalk.h \ - xtalk/xtalk_defs.h \ - xtalk/xusb.c \ - xtalk/xusb.h \ # libastribank_la_CFLAGS = $(GLOBAL_CFLAGS) +libastribank_la_LIBADD = xtalk/libxtalk.la if USE_OCTASIC libecholoader_la_SOURCES = \ diff --git a/xpp/astribank.c b/xpp/astribank.c new file mode 100644 index 0000000..2775138 --- /dev/null +++ b/xpp/astribank.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include "mpptalk.h" +#include "astribank.h" + +#define DBG_MASK 0x08 + +struct astribank { + struct xusb_device *xusb_device; + struct xusb_iface *xpp_iface; + struct xusb_iface *mpp_iface; + struct mpp_device *mpp; + char *path; +}; + + +struct astribank *astribank_new(const char *path) +{ + struct astribank *ab; + + ab = calloc(sizeof(*ab), 1); + if (!ab) { + ERR("%s: Failed allocating Astribank device\n", path); + goto err; + } + ab->xusb_device = xusb_find_bypath(path); + if (!ab->xusb_device) { + ERR("%s: Cannot find Astribank\n", path); + goto err; + } + ab->path = strdup(path); + if (!ab->path) { + ERR("%s: Failed allocating Astribank path\n", path); + goto err; + } + return ab; +err: + astribank_destroy(ab); + return NULL; +} + +void astribank_destroy(struct astribank *ab) +{ + if (ab) { + if (ab->path) + free(ab->path); + if (ab->xpp_iface) + xusb_release(ab->xpp_iface); + if (ab->mpp) { + mpp_delete(ab->mpp); /* this also closes the underlying xusb */ + ab->mpp = NULL; + } + if (ab->xusb_device) { + xusb_destroy(ab->xusb_device); + ab->xusb_device = NULL; + } + free(ab); + ab = NULL; + } +} + +struct xusb_iface *astribank_xpp_open(struct astribank *ab) +{ + int ret; + + ret = xusb_claim(ab->xusb_device, 0, &ab->xpp_iface); + if (ret < 0) { + ERR("%s: Cannot claim XPP interface\n", ab->path); + goto err; + } + DBG("%s: Claimed Astribank XPP interface\n", ab->path); + return ab->xpp_iface; +err: + if (ab->xpp_iface) + xusb_release(ab->xpp_iface); + return NULL; +} + +struct mpp_device *astribank_mpp_open(struct astribank *ab) +{ + int ret; + + ret = xusb_claim(ab->xusb_device, 1, &ab->mpp_iface); + if (ret < 0) { + ERR("%s: Cannot claim MPP interface\n", ab->path); + goto err; + } + DBG("%s: Claimed Astribank MPP interface\n", ab->path); + ab->mpp = mpp_new(ab->mpp_iface); + if (!ab->mpp) { + ERR("Failed initializing MPP protocol\n"); + goto err; + } + ret = mpp_status_query(ab->mpp); + if (ret < 0) { + ERR("status query failed (ret=%d)\n", ret); + goto err; + } + return ab->mpp; +err: + if (ab->mpp) { + mpp_delete(ab->mpp); /* this also closes the underlying xusb */ + ab->mpp = NULL; + } + return NULL; +} + +struct xusb_device *xusb_dev_of_astribank(const struct astribank *ab) +{ + assert(ab->xusb_device); + return ab->xusb_device; +} + +const char *astribank_devpath(const struct astribank *ab) +{ + return xusb_devpath(ab->xusb_device); +} + +const char *astribank_serial(const struct astribank *ab) +{ + return xusb_serial(ab->xusb_device); +} + +void show_astribank_info(const struct astribank *ab) +{ + struct xusb_device *xusb_device; + + assert(ab != NULL); + xusb_device = ab->xusb_device; + assert(xusb_device != NULL); + if(verbose <= LOG_INFO) { + xusb_showinfo(xusb_device); + } else { + const struct xusb_spec *spec; + + spec = xusb_spec(xusb_device); + printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb_device)); + printf("USB Firmware Type: [%s]\n", spec->name); + printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb_device)); + printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb_device)); + printf("USB iProduct: [%s]\n", xusb_product(xusb_device)); + } +} + +int astribank_send(struct astribank *ab, int interface_num, const char *buf, int len, int timeout) +{ + struct xusb_iface *iface; + + if (interface_num == 0) + iface = ab->xpp_iface; + else if (interface_num == 1) + iface = ab->mpp_iface; + else { + ERR("Unknown interface number (%d)\n", interface_num); + return -EINVAL; + } + return xusb_send(iface, buf, len, timeout); +} + +int astribank_recv(struct astribank *ab, int interface_num, char *buf, size_t len, int timeout) +{ + struct xusb_iface *iface; + + if (interface_num == 0) + iface = ab->xpp_iface; + else if (interface_num == 1) + iface = ab->mpp_iface; + else { + ERR("Unknown interface number (%d)\n", interface_num); + return -EINVAL; + } + return xusb_recv(iface, buf, len, timeout); +} diff --git a/xpp/astribank.h b/xpp/astribank.h new file mode 100644 index 0000000..a75513a --- /dev/null +++ b/xpp/astribank.h @@ -0,0 +1,33 @@ +#ifndef ASTRIBANK_H +#define ASTRIBANK_H + +#include + +struct astribank *astribank_new(const char *path); +void astribank_destroy(struct astribank *ab); +void show_astribank_info(const struct astribank *ab); + +struct xusb_iface *astribank_xpp_open(struct astribank *ab); +struct mpp_device *astribank_mpp_open(struct astribank *ab); + +struct xusb_device *xusb_dev_of_astribank(const struct astribank *ab); +const char *astribank_devpath(const struct astribank *ab); +const char *astribank_serial(const struct astribank *ab); + +int astribank_send(struct astribank *ab, int interface_num, const char *buf, int len, int timeout); +int astribank_recv(struct astribank *ab, int interface_num, char *buf, size_t len, int timeout); + + +#define AB_REPORT(report_type, astribank, fmt, ...) \ + report_type("%s [%s]: " fmt, \ + astribank_devpath(astribank), \ + astribank_serial(astribank), \ + ## __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_H */ diff --git a/xpp/astribank_allow.c b/xpp/astribank_allow.c index 8f1ea92..dd8d9d3 100644 --- a/xpp/astribank_allow.c +++ b/xpp/astribank_allow.c @@ -31,9 +31,9 @@ #include #include #include -#include "mpp.h" +#include #include "mpptalk.h" -#include +#include "astribank.h" #include "astribank_license.h" static const char rcsid[] = "$Id$"; @@ -55,28 +55,11 @@ static void usage() exit(1); } -static int capabilities_burn( - struct astribank_device *astribank, - struct eeprom_table *eeprom_table, - struct capabilities *capabilities, - struct capkey *key) -{ - int ret; - - INFO("Burning capabilities\n"); - ret = mpp_caps_set(astribank, eeprom_table, capabilities, key); - if(ret < 0) { - ERR("Capabilities burning failed: %d\n", ret); - return ret; - } - INFO("Done\n"); - return 0; -} - int main(int argc, char *argv[]) { char *devpath = NULL; - struct astribank_device *astribank; + struct astribank *astribank; + struct mpp_device *mpp; struct eeprom_table eeprom_table; struct capabilities caps; struct capkey key; @@ -127,16 +110,19 @@ int main(int argc, char *argv[]) usage(); } DBG("Startup %s\n", devpath); - if((astribank = mpp_init(devpath, 1)) == NULL) { - ERR("Failed initializing MPP\n"); + astribank = astribank_new(devpath); + if(!astribank) { + ERR("Failed initializing Astribank\n"); return 1; } - if(astribank->eeprom_type != EEPROM_TYPE_LARGE) { + mpp = astribank_mpp_open(astribank); + ret = mpp_eeprom_type(mpp); + if(ret != EEPROM_TYPE_LARGE) { ERR("Cannot use this program with astribank EEPROM type %d (need %d)\n", - astribank->eeprom_type, EEPROM_TYPE_LARGE); + ret, EEPROM_TYPE_LARGE); return 1; } - ret = mpp_caps_get(astribank, &eeprom_table, &caps, &key); + ret = mpp_caps_get(mpp, &eeprom_table, &caps, &key); if(ret < 0) { ERR("Failed to get original capabilities: %d\n", ret); return 1; @@ -158,8 +144,13 @@ int main(int argc, char *argv[]) return 1; } show_capabilities(&caps, stderr); - if (capabilities_burn(astribank, &eeprom_table, &caps, &key) < 0) + INFO("Burning capabilities\n"); + ret = mpp_caps_set(mpp, &eeprom_table, &caps, &key); + if(ret < 0) { + ERR("Capabilities burning failed: %d\n", ret); return 1; + } + INFO("Done\n"); if (file != stdin) fclose(file); } else { @@ -180,6 +171,6 @@ int main(int argc, char *argv[]) if (file != stdout) fclose(file); } - mpp_exit(astribank); + astribank_destroy(astribank); return 0; } diff --git a/xpp/astribank_hexload.c b/xpp/astribank_hexload.c index ffc158a..c170968 100644 --- a/xpp/astribank_hexload.c +++ b/xpp/astribank_hexload.c @@ -28,13 +28,14 @@ #include #include #include -#include +#include +#include +#include #include "hexfile.h" #include "mpptalk.h" +#include "astribank.h" #include "pic_loader.h" #include "echo_loader.h" -#include "astribank_usb.h" -#include "../autoconfig.h" #define DBG_MASK 0x80 #define MAX_HEX_LINES 64000 @@ -61,7 +62,7 @@ static void usage() exit(1); } -int handle_hexline(struct astribank_device *astribank, struct hexline *hexline) +int handle_hexline(struct mpp_device *mpp, struct hexline *hexline) { uint16_t len; uint16_t offset_dummy; @@ -69,7 +70,7 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline) int ret; assert(hexline); - assert(astribank); + assert(mpp); if(hexline->d.content.header.tt != TT_DATA) { DBG("Non data record type = %d\n", hexline->d.content.header.tt); return 0; @@ -77,7 +78,7 @@ int handle_hexline(struct astribank_device *astribank, struct hexline *hexline) len = hexline->d.content.header.ll; offset_dummy = hexline->d.content.header.offset; data = hexline->d.content.tt_data.data; - if((ret = mpp_send_seg(astribank, data, offset_dummy, len)) < 0) { + if((ret = mpp_send_seg(mpp, data, offset_dummy, len)) < 0) { ERR("Failed hexfile send line: %d\n", ret); return -EINVAL; } @@ -100,7 +101,7 @@ static void print_parse_errors(int level, const char *msg, ...) } } -static int load_hexfile(struct astribank_device *astribank, const char *hexfile, enum dev_dest dest) +static int load_hexfile(struct mpp_device *mpp, const char *hexfile, enum dev_dest dest) { struct hexdata *hexdata = NULL; int finished = 0; @@ -108,19 +109,24 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile, unsigned i; char star[] = "+\\+|+/+-"; const char *devstr; + struct xusb_device *xusb_device; + struct xusb_iface *xusb_iface; + parse_hexfile_set_reporting(print_parse_errors); if((hexdata = parse_hexfile(hexfile, MAX_HEX_LINES)) == NULL) { perror(hexfile); return -errno; } - devstr = xusb_devpath(astribank->xusb); + xusb_iface = xubs_iface_of_mpp(mpp); + xusb_device = xusb_deviceof(xusb_iface); + devstr = xusb_devpath(xusb_device); INFO("%s [%s]: Loading %s Firmware: %s (version %s)\n", devstr, - xusb_serial(astribank->xusb), + xusb_serial(xusb_device), dev_dest2str(dest), hexdata->fname, hexdata->version_info); - if((ret = mpp_send_start(astribank, dest, hexdata->version_info)) < 0) { + if((ret = mpp_send_start(mpp, dest, hexdata->version_info)) < 0) { ERR("%s: Failed hexfile send start: %d\n", devstr, ret); return ret; } @@ -142,7 +148,7 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile, finished = 1; continue; } - if((ret = handle_hexline(astribank, hexline)) < 0) { + if((ret = handle_hexline(mpp, hexline)) < 0) { ERR("%s: Failed hexfile sending in lineno %d (ret=%d)\n", devstr, i, ret);; return ret; } @@ -151,7 +157,7 @@ static int load_hexfile(struct astribank_device *astribank, const char *hexfile, putchar('\n'); fflush(stdout); } - if((ret = mpp_send_end(astribank)) < 0) { + if((ret = mpp_send_end(mpp)) < 0) { ERR("%s: Failed hexfile send end: %d\n", devstr, ret); return ret; } @@ -178,7 +184,6 @@ int main(int argc, char *argv[]) int opt_sum = 0; enum dev_dest dest = DEST_NONE; const char options[] = "vd:D:EFOopAS:"; - int iface_num; int ret; progname = argv[0]; @@ -247,7 +252,6 @@ int main(int argc, char *argv[]) " and -p options are mutually exclusive, if neither is used then -o should present\n"); usage(); } - iface_num = (opt_dest) ? 1 : 0; if(!opt_pic && !opt_ecver) { if(optind != argc - 1) { ERR("Got %d hexfile names (Need exactly one hexfile)\n", @@ -270,29 +274,43 @@ int main(int argc, char *argv[]) /* * MPP Interface */ - struct astribank_device *astribank; + struct astribank *astribank; + struct mpp_device *mpp; - if((astribank = mpp_init(devpath, iface_num)) == NULL) { + astribank = astribank_new(devpath); + if(!astribank) { ERR("%s: Opening astribank failed\n", devpath); return 1; } - //show_astribank_info(astribank); - if(load_hexfile(astribank, argv[optind], dest) < 0) { + mpp = astribank_mpp_open(astribank); + if(!mpp) { + ERR("%s: Opening astribank XPP interface failed\n", devpath); + return 1; + } + show_astribank_info(astribank); + if(load_hexfile(mpp, argv[optind], dest) < 0) { ERR("%s: Loading firmware to %s failed\n", devpath, dev_dest2str(dest)); return 1; } - astribank_close(astribank, 0); + astribank_destroy(astribank); } else if(opt_pic || opt_echo || opt_ecver) { /* * XPP Interface */ - struct astribank_device *astribank; + struct astribank *astribank; + struct xusb_iface *xpp_iface; - if((astribank = astribank_open(devpath, iface_num)) == NULL) { + astribank = astribank_new(devpath); + if (!astribank) { ERR("%s: Opening astribank failed\n", devpath); return 1; } - //show_astribank_info(astribank); + xpp_iface = astribank_xpp_open(astribank); + if(!xpp_iface) { + ERR("%s: Opening astribank XPP interface failed\n", devpath); + return 1; + } + show_astribank_info(astribank); #if HAVE_OCTASIC if (opt_ecver) { if((ret = echo_ver(astribank)) < 0) { @@ -315,7 +333,7 @@ int main(int argc, char *argv[]) } #endif } - astribank_close(astribank, 0); + astribank_destroy(astribank); } return 0; } diff --git a/xpp/astribank_license.c b/xpp/astribank_license.c index 88d2af7..79730d5 100644 --- a/xpp/astribank_license.c +++ b/xpp/astribank_license.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "astribank_license.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) diff --git a/xpp/astribank_license.h b/xpp/astribank_license.h index 74d6a31..b036fc4 100644 --- a/xpp/astribank_license.h +++ b/xpp/astribank_license.h @@ -1,7 +1,7 @@ #ifndef ASTRIBANK_ALLOW_H #define ASTRIBANK_ALLOW_H -#include "mpp.h" +#include "mpptalk.h" enum license_markers { LICENSE_MARKER_NONE = 0, diff --git a/xpp/astribank_tool.c b/xpp/astribank_tool.c index f3ca976..7be04fb 100644 --- a/xpp/astribank_tool.c +++ b/xpp/astribank_tool.c @@ -28,10 +28,10 @@ #include #include #include -#include "astribank_usb.h" +#include +#include #include "mpptalk.h" -#include -#include +#include "astribank.h" #define DBG_MASK 0x80 /* if enabled, adds support for resetting pre-MPP USB firmware - if we @@ -76,90 +76,11 @@ static int reset_kind(const char *arg) return -1; } - -static int show_hardware(struct astribank_device *astribank) -{ - int ret; - struct eeprom_table eeprom_table; - struct capabilities capabilities; - struct extrainfo extrainfo; - - ret = mpp_caps_get(astribank, &eeprom_table, &capabilities, NULL); - if(ret < 0) - return ret; - show_eeprom(&eeprom_table, stdout); - show_astribank_status(astribank, stdout); - if(astribank->eeprom_type == EEPROM_TYPE_LARGE) { - show_capabilities(&capabilities, stdout); - if(STATUS_FPGA_LOADED(astribank->status)) { - uint8_t unit; - uint8_t card_status; - uint8_t card_type; - uint8_t fpga_configuration; - uint8_t status; - - for(unit = 0; unit < 5; unit++) { - ret = mpps_card_info(astribank, unit, &card_type, &card_status); - if(ret < 0) - return ret; - printf("CARD %d: type=%x.%x %s\n", unit, - ((card_type >> 4) & 0xF), (card_type & 0xF), - ((card_status & 0x1) ? "PIC" : "NOPIC")); - } - ret = mpps_stat(astribank, unit, &fpga_configuration, &status); - if (ret < 0) - return ret; - printf("FPGA: %-17s: %d\n", "Configuration num", fpga_configuration); - printf("FPGA: %-17s: %s\n", "Watchdog Timer", - (SER_STAT_WATCHDOG_READY(status)) ? "ready" : "expired"); - printf("FPGA: %-17s: %s\n", "XPD Alive", - (SER_STAT_XPD_ALIVE(status)) ? "yes" : "no"); - } - ret = mpp_extrainfo_get(astribank, &extrainfo); - if(ret < 0) - return ret; - show_extrainfo(&extrainfo, stdout); - if(CAP_EXTRA_TWINSTAR(&capabilities)) { - twinstar_show(astribank, stdout); - } - } - return 0; -} - -#ifdef SUPPORT_OLD_RESET -/* Try to reset a device using USB_FW.hex, up to Xorcom rev. 6885 */ -int old_reset(const char* devpath) -{ - struct astribank_device *astribank; - int ret; - struct { - uint8_t op; - } PACKED header = {0x20}; /* PT_RESET */ - char *buf = (char*) &header; - - /* Note that the function re-opens the connection to the Astribank - * as any reference to the previous connection was lost when mpp_open - * returned NULL as the astribank reference. */ - astribank = astribank_open(devpath, 1); - if (!astribank) { - DBG("Failed re-opening astribank device for old_reset\n"); - return -ENODEV; - } - ret = xusb_send(astribank->xusb, buf, 1, 5000); - - /* If we just had a reenumeration, we may get -ENODEV */ - if(ret < 0 && ret != -ENODEV) - return ret; - /* We don't astribank_close(), as it has likely been - * reenumerated by now. */ - return 0; -} -#endif /* SUPPORT_OLD_RESET */ - int main(int argc, char *argv[]) { char *devpath = NULL; - struct astribank_device *astribank; + struct astribank *astribank; + struct mpp_device *mpp; const char options[] = "vd:D:nr:p:w:Q"; int opt_renumerate = 0; char *opt_port = NULL; @@ -218,20 +139,12 @@ int main(int argc, char *argv[]) usage(); } DBG("Startup %s\n", devpath); - if((astribank = mpp_init(devpath, 1)) == NULL) { - ERR("Failed initializing MPP\n"); -#ifdef SUPPORT_OLD_RESET - DBG("opt_reset = %s\n", opt_reset); - if (opt_reset) { - DBG("Trying old reset method\n"); - if ((ret = old_reset(devpath)) != 0) { - ERR("Old reset method failed as well: %d\n", ret); - } - } -#endif /* SUPPORT_OLD_RESET */ - + astribank = astribank_new(devpath); + if(!astribank) { + ERR("Failed initializing Astribank\n"); return 1; } + mpp = astribank_mpp_open(astribank); /* * First process reset options. We want to be able * to reset minimal USB firmwares even if they don't @@ -245,7 +158,7 @@ int main(int argc, char *argv[]) return 1; } DBG("Reseting (%s)\n", opt_reset); - if((ret = mpp_reset(astribank, full_reset)) < 0) { + if((ret = mpp_reset(mpp, full_reset)) < 0) { ERR("%s Reseting astribank failed: %d\n", (full_reset) ? "Full" : "Half", ret); } @@ -253,10 +166,10 @@ int main(int argc, char *argv[]) } show_astribank_info(astribank); if(opt_query) { - show_hardware(astribank); + show_hardware(mpp); } else if(opt_renumerate) { DBG("Renumerate\n"); - if((ret = mpp_renumerate(astribank)) < 0) { + if((ret = mpp_renumerate(mpp)) < 0) { ERR("Renumerating astribank failed: %d\n", ret); } } else if(opt_watchdog) { @@ -264,24 +177,24 @@ int main(int argc, char *argv[]) DBG("TWINSTAR: Setting watchdog %s-guard\n", (watchdogstate) ? "on" : "off"); - if((ret = mpp_tws_setwatchdog(astribank, watchdogstate)) < 0) { + if((ret = mpp_tws_setwatchdog(mpp, watchdogstate)) < 0) { ERR("Failed to set watchdog to %d\n", watchdogstate); return 1; } } else if(opt_port) { int new_portnum = strtoul(opt_port, NULL, 0); - int tws_portnum = mpp_tws_portnum(astribank); + int tws_portnum = mpp_tws_portnum(mpp); char *msg = (new_portnum == tws_portnum) ? " Same same, never mind..." : ""; DBG("TWINSTAR: Setting portnum to %d.%s\n", new_portnum, msg); - if((ret = mpp_tws_setportnum(astribank, new_portnum)) < 0) { + if((ret = mpp_tws_setportnum(mpp, new_portnum)) < 0) { ERR("Failed to set USB portnum to %d\n", new_portnum); return 1; } } out: - mpp_exit(astribank); + astribank_destroy(astribank); return 0; } diff --git a/xpp/astribank_usb.c b/xpp/astribank_usb.c deleted file mode 100644 index af7e6aa..0000000 --- a/xpp/astribank_usb.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Written by Oron Peled - * Copyright (C) 2008, 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. - * - */ - -#define _GNU_SOURCE /* for memrchr() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "astribank_usb.h" -#include - -static const char rcsid[] = "$Id$"; - -#define DBG_MASK 0x01 -#define TIMEOUT 500 - -#define TYPE_ENTRY(t,p,ni,n,ne,out,in,...) \ - { \ - .my_vendor_id = 0xe4e4, \ - .my_product_id = (p), \ - .name = #t, \ - .num_interfaces = (ni), \ - .my_interface_num = (n), \ - .num_endpoints = (ne), \ - .my_ep_in = (in), \ - .my_ep_out = (out), \ - } - -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -static const struct xusb_spec astribank_specs[] = { - /* OLD Firmwares */ - TYPE_ENTRY("USB-OLDFXS", 0x1131, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - TYPE_ENTRY("FPGA-OLDFXS", 0x1132, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - TYPE_ENTRY("USB-BRI", 0x1141, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - TYPE_ENTRY("FPGA-BRI", 0x1142, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - TYPE_ENTRY("USB-OLD", 0x1151, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - TYPE_ENTRY("FPGA-OLD", 0x1152, 2, 1, 2, MP_EP_OUT, MP_EP_IN), - - 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[] = { - TYPE_ENTRY("USB_PIC", 0x1161, 2, 0, 2, XPP_EP_OUT, XPP_EP_IN), -}; -#undef TYPE_ENTRY - -//static int verbose = LOG_DEBUG; - -/* - * USB handling - */ -struct astribank_device *astribank_open(const char devpath[], int iface_num) -{ - struct astribank_device *astribank = NULL; - struct xusb *xusb; - - DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); - if((astribank = malloc(sizeof(struct astribank_device))) == NULL) { - ERR("Out of memory\n"); - goto fail; - } - memset(astribank, 0, sizeof(*astribank)); - if (iface_num) { - xusb = xusb_find_bypath(astribank_specs, ARRAY_SIZE(astribank_specs), devpath); - } else { - xusb = xusb_find_bypath(astribank_pic_specs, ARRAY_SIZE(astribank_pic_specs), devpath); - } - if (!xusb) { - ERR("%s: No device found\n", __func__); - goto fail; - } - astribank->xusb = xusb; - astribank->is_usb2 = (xusb_packet_size(xusb) == 512); - astribank->my_interface_num = iface_num; - if (xusb_claim_interface(astribank->xusb) < 0) { - ERR("xusb_claim_interface failed\n"); - goto fail; - } - astribank->tx_sequenceno = 1; - return astribank; -fail: - if (astribank) { - free(astribank); - astribank = NULL; - } - return NULL; -} - -/* - * MP device handling - */ -void show_astribank_info(const struct astribank_device *astribank) -{ - struct xusb *xusb; - - assert(astribank != NULL); - xusb = astribank->xusb; - assert(xusb != NULL); - if(verbose <= LOG_INFO) { - xusb_showinfo(xusb); - } else { - const struct xusb_spec *spec; - - spec = xusb_spec(xusb); - printf("USB Bus/Device: [%s]\n", xusb_devpath(xusb)); - printf("USB Firmware Type: [%s]\n", spec->name); - printf("USB iSerialNumber: [%s]\n", xusb_serial(xusb)); - printf("USB iManufacturer: [%s]\n", xusb_manufacturer(xusb)); - printf("USB iProduct: [%s]\n", xusb_product(xusb)); - } -} - -void astribank_close(struct astribank_device *astribank, int disconnected) -{ - assert(astribank != NULL); - if (astribank->xusb) { - xusb_close(astribank->xusb); - astribank->xusb = NULL; - } - astribank->tx_sequenceno = 0; -} - -#if 0 -int flush_read(struct astribank_device *astribank) -{ - char tmpbuf[BUFSIZ]; - int ret; - - DBG("starting...\n"); - memset(tmpbuf, 0, BUFSIZ); - ret = recv_usb(astribank, tmpbuf, BUFSIZ, 1); - if(ret < 0 && ret != -ETIMEDOUT) { - ERR("ret=%d\n", ret); - return ret; - } else if(ret > 0) { - DBG("Got %d bytes:\n", ret); - dump_packet(LOG_DEBUG, DBG_MASK, __FUNCTION__, tmpbuf, ret); - } - return 0; -} -#endif - - -int release_isvalid(uint16_t release) -{ - uint8_t rmajor = (release >> 8) & 0xFF; - uint8_t rminor = release & 0xFF; - - return (rmajor > 0) && - (rmajor < 10) && - (rminor > 0) && - (rminor < 10); -} - -int label_isvalid(const char *label) -{ - int len; - int goodlen; - const char GOOD_CHARS[] = - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "-_."; - - len = strlen(label); - goodlen = strspn(label, GOOD_CHARS); - if(len > LABEL_SIZE) { - ERR("Label too long (%d > %d)\n", len, LABEL_SIZE); - return 0; - } - if(goodlen != len) { - ERR("Bad character in label (pos=%d)\n", goodlen); - return 0; - } - return 1; -} - -int eeprom_fill(struct eeprom_table *eprm, - const char *vendor, - const char *product, - const char *release, - const char *label) -{ - uint16_t val; - - eprm->source = 0xC0; - eprm->config_byte = 0; - if(vendor) { - val = strtoul(vendor, NULL, 0); - if(!val) { - ERR("Invalid vendor '%s'\n", - vendor); - return -EINVAL; - } - eprm->vendor = val; - } - if(product) { - val = strtoul(product, NULL, 0); - if(!val) { - ERR("Invalid product '%s'\n", - product); - return -EINVAL; - } - eprm->product = val; - } - if(release) { - int release_major = 0; - int release_minor = 0; - uint16_t value; - - if(sscanf(release, "%d.%d", &release_major, &release_minor) != 2) { - ERR("Failed to parse release number '%s'\n", release); - return -EINVAL; - } - value = (release_major << 8) | release_minor; - DBG("Parsed release(%d): major=%d, minor=%d\n", - value, release_major, release_minor); - if(!release_isvalid(value)) { - ERR("Invalid release number 0x%X\n", value); - return -EINVAL; - } - eprm->release = value; - } - if(label) { - /* padding */ - if(!label_isvalid(label)) { - ERR("Invalid label '%s'\n", label); - return -EINVAL; - } - memset(eprm->label, 0, LABEL_SIZE); - memcpy(eprm->label, label, strlen(label)); - } - return 0; -} - -int astribank_has_twinstar(struct astribank_device *astribank) -{ - uint16_t product_series; - - assert(astribank != NULL); - product_series = xusb_product_id(astribank->xusb); - product_series &= 0xFFF0; - if(product_series == 0x1160) /* New boards */ - return 1; - return 0; -} - diff --git a/xpp/astribank_usb.h b/xpp/astribank_usb.h deleted file mode 100644 index 69778e6..0000000 --- a/xpp/astribank_usb.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef ASTRIBANK_USB_H -#define ASTRIBANK_USB_H -/* - * Written by Oron Peled - * Copyright (C) 2008, 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 -#include -#include -#include "mpp.h" - -/* - * Astribank handling - */ - -#define PACKET_SIZE 512 - -/* USB Endpoints */ -#define MP_EP_OUT 0x04 /* Managment processor */ -#define MP_EP_IN 0x88 /* Managment processor */ - -#define XPP_EP_OUT 0x02 /* XPP */ -#define XPP_EP_IN 0x86 /* XPP */ - -/* USB firmware types */ -#define USB_11xx 0 -#define USB_FIRMWARE_II 1 -#define USB_PIC 2 - -struct interface_type { - int type_code; - int num_interfaces; - int my_interface_num; - int num_endpoints; - int my_ep_out; - int my_ep_in; - char *name; - int endpoints[4]; /* for matching */ -}; - -enum eeprom_burn_state { - BURN_STATE_NONE = 0, - BURN_STATE_STARTED = 1, - BURN_STATE_ENDED = 2, - BURN_STATE_FAILED = 3, -}; - -struct astribank_device { - struct xusb *xusb; - struct xtalk_device *xtalk_dev; - usb_dev_handle *handle; - int my_interface_num; - int my_ep_out; - int my_ep_in; - char iInterface[BUFSIZ]; - int is_usb2; - enum eeprom_type eeprom_type; - enum eeprom_burn_state burn_state; - uint8_t status; - uint8_t mpp_proto_version; - struct eeprom_table *eeprom; - struct firmware_versions fw_versions; - uint16_t tx_sequenceno; -}; - -/* - * Prototypes - */ -struct astribank_device *astribank_open(const char devpath[], int iface_num); -void astribank_close(struct astribank_device *astribank, int disconnected); -void show_astribank_info(const struct astribank_device *astribank); -int send_usb(struct astribank_device *astribank, char *buf, int len, int timeout); -int recv_usb(struct astribank_device *astribank, char *buf, size_t len, int timeout); -int flush_read(struct astribank_device *astribank); -int eeprom_fill(struct eeprom_table *eprm, - const char *vendor, - const char *product, - const char *release, - const char *label); -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 */ diff --git a/xpp/echo_loader.c b/xpp/echo_loader.c index ca92883..827f6ef 100644 --- a/xpp/echo_loader.c +++ b/xpp/echo_loader.c @@ -28,12 +28,21 @@ #include #include #include -#include "echo_loader.h" -#include "debug.h" +#include #include +#include +#include +#include +#include "echo_loader.h" #include "parse_span_specs.h" -#define DBG_MASK 0x03 +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#define PACKED +#endif + +#define DBG_MASK 0x10 #define TIMEOUT 1000 #define ECHO_MAX_CHANS 128 #define ECHO_RIN_STREAM 0 @@ -53,7 +62,7 @@ static float oct_fw_load_timeout = 2.0; struct echo_mod { tPOCT6100_INSTANCE_API pApiInstance; UINT32 ulEchoChanHndl[256]; - struct astribank_device *astribank; + struct astribank *astribank; int maxchans; }; @@ -100,9 +109,9 @@ static struct usb_buffer { } usb_buffer; -static void usb_buffer_init(struct astribank_device *astribank, struct usb_buffer *ub) +static void usb_buffer_init(struct astribank *astribank, struct usb_buffer *ub) { - ub->max_len = xusb_packet_size(astribank->xusb); + ub->max_len = xusb_packet_size(xusb_dev_of_astribank(astribank)); ub->curr = 0; ub->min_send = INT_MAX; ub->max_send = 0; @@ -120,7 +129,7 @@ static long usb_buffer_usec(struct usb_buffer *ub) (now.tv_usec - ub->start.tv_usec); } -static void usb_buffer_showstatistics(struct astribank_device *astribank, struct usb_buffer *ub) +static void usb_buffer_showstatistics(struct astribank *astribank, struct usb_buffer *ub) { long usec; @@ -133,7 +142,7 @@ static void usb_buffer_showstatistics(struct astribank_device *astribank, struct usec / 1000, usec / ub->num_sends); } -static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffer *ub) +static int usb_buffer_flush(struct astribank *astribank, struct usb_buffer *ub) { int ret; long t; @@ -142,7 +151,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe if (ub->curr == 0) return 0; - ret = xusb_send(astribank->xusb, ub->data, ub->curr, TIMEOUT); + ret = astribank_send(astribank, 0, ub->data, ub->curr, TIMEOUT); if (ret < 0) { AB_ERR(astribank, "xusb_send failed: %d\n", ret); return ret; @@ -175,7 +184,7 @@ static int usb_buffer_flush(struct astribank_device *astribank, struct usb_buffe return ret; } -static int usb_buffer_append(struct astribank_device *astribank, struct usb_buffer *ub, +static int usb_buffer_append(struct astribank *astribank, struct usb_buffer *ub, char *buf, int len) { if (ub->curr + len >= ub->max_len) { @@ -188,7 +197,7 @@ static int usb_buffer_append(struct astribank_device *astribank, struct usb_buff return len; } -static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer *ub, +static int usb_buffer_send(struct astribank *astribank, struct usb_buffer *ub, char *buf, int len, int timeout, int recv_answer) { int ret = 0; @@ -209,7 +218,7 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer ret = usb_buffer_flush(astribank, ub); if (ret < 0) return ret; - ret = xusb_recv(astribank->xusb, buf, PACKET_SIZE, TIMEOUT); + ret = astribank_recv(astribank, 0, buf, PACKET_SIZE, TIMEOUT); if (ret <= 0) { AB_ERR(astribank, "No USB packs to read: %s\n", strerror(-ret)); return -EINVAL; @@ -239,7 +248,7 @@ static int usb_buffer_send(struct astribank_device *astribank, struct usb_buffer return ret; } -int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver) +int spi_send(struct astribank *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver) { int ret; char buf[PACKET_SIZE]; @@ -272,7 +281,7 @@ int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, i return ret; } -int test_send(struct astribank_device *astribank) +int test_send(struct astribank *astribank) { int ret; char buf[PACKET_SIZE]; @@ -300,7 +309,7 @@ int test_send(struct astribank_device *astribank) return ret; } -int echo_send_data(struct astribank_device *astribank, const unsigned int addr, const unsigned int data) +int echo_send_data(struct astribank *astribank, const unsigned int addr, const unsigned int data) { int ret; /* DBG("SEND: %04X -> [%04X]\n", data, addr); @@ -330,7 +339,7 @@ failed: return ret; } -int echo_recv_data(struct astribank_device *astribank, const unsigned int addr) +int echo_recv_data(struct astribank *astribank, const unsigned int addr) { unsigned int data = 0x00; int ret; @@ -452,7 +461,7 @@ UINT32 Oct6100UserDriverWriteApi(tPOCT6100_WRITE_PARAMS f_pWriteParams) const unsigned int addr = f_pWriteParams->ulWriteAddress; 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; + struct astribank *astribank = echo_mod->astribank; int ret; ret = echo_send_data(astribank, addr, data); @@ -469,7 +478,7 @@ UINT32 Oct6100UserDriverWriteSmearApi(tPOCT6100_WRITE_SMEAR_PARAMS f_pSmearParam unsigned int data; unsigned int len; const struct echo_mod *echo_mod; - struct astribank_device *astribank; + struct astribank *astribank; unsigned int i; len = f_pSmearParams->ulWriteLength; @@ -495,7 +504,7 @@ UINT32 Oct6100UserDriverWriteBurstApi(tPOCT6100_WRITE_BURST_PARAMS f_pBurstParam unsigned int data; unsigned int len = f_pBurstParams->ulWriteLength; const struct echo_mod *echo_mod = (struct echo_mod *)f_pBurstParams->pProcessContext; - struct astribank_device *astribank = echo_mod->astribank; + struct astribank *astribank = echo_mod->astribank; unsigned int i; for (i = 0; i < len; i++) { @@ -516,7 +525,7 @@ UINT32 Oct6100UserDriverReadApi(tPOCT6100_READ_PARAMS f_pReadParams) { const unsigned int addr = f_pReadParams->ulReadAddress; const struct echo_mod *echo_mod; - struct astribank_device *astribank; + struct astribank *astribank; int ret; echo_mod = (struct echo_mod *)f_pReadParams->pProcessContext; @@ -535,7 +544,7 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams) unsigned int addr; unsigned int len; const struct echo_mod *echo_mod; - struct astribank_device *astribank; + struct astribank *astribank; unsigned int i; len = f_pBurstParams->ulReadLength; @@ -555,13 +564,13 @@ UINT32 Oct6100UserDriverReadBurstApi(tPOCT6100_READ_BURST_PARAMS f_pBurstParams) return cOCT6100_ERR_OK; } -inline int get_ver(struct astribank_device *astribank) +inline int get_ver(struct astribank *astribank) { return spi_send(astribank, 0, 0, 1, 1); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct span_specs *span_specs) +UINT32 init_octasic(char *filename, struct astribank *astribank, struct span_specs *span_specs) { int cpld_ver; struct echo_mod *echo_mod; @@ -838,7 +847,7 @@ UINT32 init_octasic(char *filename, struct astribank_device *astribank, struct s } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -int load_echo(struct astribank_device *astribank, char *filename, int default_is_alaw, const char *span_spec) +int load_echo(struct astribank *astribank, char *filename, int default_is_alaw, const char *span_spec) { int ret; UINT32 octasic_status; @@ -868,7 +877,7 @@ int load_echo(struct astribank_device *astribank, char *filename, int default_is return 0; } -int echo_ver(struct astribank_device *astribank) +int echo_ver(struct astribank *astribank) { usb_buffer_init(astribank, &usb_buffer); return get_ver(astribank); diff --git a/xpp/echo_loader.h b/xpp/echo_loader.h index 2bffda2..d361d8a 100644 --- a/xpp/echo_loader.h +++ b/xpp/echo_loader.h @@ -23,10 +23,10 @@ */ #include -#include "astribank_usb.h" +#include "astribank.h" -int spi_send(struct astribank_device *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver); -int load_echo(struct astribank_device *astribank, char *filename, int is_alaw, const char *span_spec); -int echo_ver(struct astribank_device *astribank); +int spi_send(struct astribank *astribank, uint16_t addr, uint16_t data, int recv_answer, int ver); +int load_echo(struct astribank *astribank, char *filename, int is_alaw, const char *span_spec); +int echo_ver(struct astribank *astribank); #endif /* ECHO_LOADER_H */ diff --git a/xpp/mpp.h b/xpp/mpp.h deleted file mode 100644 index 53ea81e..0000000 --- a/xpp/mpp.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef MPP_H -#define MPP_H -/* - * Written by Oron Peled - * Copyright (C) 2008, 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. - * - */ - -/* - * MPP - Managment Processor Protocol definitions - */ - -#include -#include -#include - -#ifdef __GNUC__ -#define PACKED __attribute__((packed)) -#else -#error "We do not know how your compiler packs structures" -#endif - -#define MK_PROTO_VERSION(major, minor) (((major) << 4) | (0x0F & (minor))) - -#define MPP_PROTOCOL_VERSION MK_PROTO_VERSION(1,4) -#define MPP_SUPPORTED_VERSION(x) ((x) == MK_PROTO_VERSION(1,3) || (x) == MK_PROTO_VERSION(1,4)) - -/* - * The eeprom_table is common to all eeprom types. - */ -#define LABEL_SIZE 8 -struct eeprom_table { - uint8_t source; /* C0 - small eeprom, C2 - large eeprom */ - uint16_t vendor; - uint16_t product; - uint16_t release; /* BCD encoded release */ - uint8_t config_byte; /* Must be 0 */ - uint8_t label[LABEL_SIZE]; -} PACKED; - -#define VERSION_LEN 6 -struct firmware_versions { - char usb[VERSION_LEN]; - char fpga[VERSION_LEN]; - char eeprom[VERSION_LEN]; -} PACKED; - -struct capabilities { - uint8_t ports_fxs; - uint8_t ports_fxo; - uint8_t ports_bri; - uint8_t ports_pri; - uint8_t extra_features; /* BIT(0) - TwinStar */ - uint8_t ports_echo; - uint8_t reserved[2]; - uint32_t timestamp; -} PACKED; - -#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01) -#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0) -#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0) - -#define KEYSIZE 16 - -struct capkey { - uint8_t k[KEYSIZE]; -} PACKED; - -struct extrainfo { - char text[EXTRAINFO_SIZE]; -} PACKED; - -struct mpp_header { - uint16_t len; - uint16_t seq; - uint8_t op; /* MSB: 0 - to device, 1 - from device */ -} PACKED; - -enum mpp_ser_op { - SER_CARD_INFO_GET = 0x1, - SER_STAT_GET = 0x3, -/* Status bits */ -#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01) -#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02) -}; - -/* Individual commands structure */ - -CMD_DEF(MPP, STATUS_GET); - - -CMD_DEF(MPP, STATUS_GET_REPLY, - uint8_t i2cs_data; - -#define STATUS_FPGA_LOADED(x) ((x) & 0x01) - uint8_t status; /* BIT(0) - FPGA is loaded */ - struct firmware_versions fw_versions; - ); - -CMD_DEF(MPP, EEPROM_SET, - struct eeprom_table data; - ); - -CMD_DEF(MPP, CAPS_GET); - -CMD_DEF(MPP, CAPS_GET_REPLY, - struct eeprom_table data; - struct capabilities capabilities; - struct capkey key; - ); - -CMD_DEF(MPP, CAPS_SET, - struct eeprom_table data; - struct capabilities capabilities; - struct capkey key; - ); - -CMD_DEF(MPP, EXTRAINFO_GET); - -CMD_DEF(MPP, EXTRAINFO_GET_REPLY, - struct extrainfo info; - ); - -CMD_DEF(MPP, EXTRAINFO_SET, - struct extrainfo info; - ); - -CMD_DEF(MPP, RENUM); - -CMD_DEF(MPP, EEPROM_BLK_RD, - uint16_t offset; - uint16_t len; - ); - -CMD_DEF(MPP, EEPROM_BLK_RD_REPLY, - uint16_t offset; - uint8_t data[0]; - ); - -CMD_DEF(MPP, DEV_SEND_START, - uint8_t dest; - char ihex_version[VERSION_LEN]; - ); - -CMD_DEF(MPP, DEV_SEND_END); - -CMD_DEF(MPP, DEV_SEND_SEG, - uint16_t offset; - uint8_t data[0]; - ); - -CMD_DEF(MPP, RESET); -CMD_DEF(MPP, HALF_RESET); - -CMD_DEF(MPP, SER_SEND, - uint8_t data[0]; - ); - -CMD_DEF(MPP, SER_RECV, - uint8_t data[0]; - ); - -CMD_DEF(MPP, TWS_WD_MODE_SET, - uint8_t wd_active; - ); - -CMD_DEF(MPP, TWS_WD_MODE_GET); -CMD_DEF(MPP, TWS_WD_MODE_GET_REPLY, - uint8_t wd_active; - ); - -CMD_DEF(MPP, TWS_PORT_SET, - uint8_t portnum; - ); - -CMD_DEF(MPP, TWS_PORT_GET); -CMD_DEF(MPP, TWS_PORT_GET_REPLY, - uint8_t portnum; - ); - -CMD_DEF(MPP, TWS_PWR_GET); -CMD_DEF(MPP, TWS_PWR_GET_REPLY, - uint8_t power; - ); - -#endif /* MPP_H */ diff --git a/xpp/mpptalk.c b/xpp/mpptalk.c index 9bab867..fdb34f1 100644 --- a/xpp/mpptalk.c +++ b/xpp/mpptalk.c @@ -26,46 +26,19 @@ #include #include #include +#include +#include #include "hexfile.h" -#include "astribank_usb.h" -#include "mpp.h" #include "mpptalk.h" -#include -#include -#include -static const char rcsid[] = "$Id$"; +#define DBG_MASK 0x04 -#define DBG_MASK 0x02 - -const char *ack_status_msg(uint8_t status) -{ - const static char *msgs[] = { - [STAT_OK] = "Acknowledges previous command", - [STAT_FAIL] = "Last command failed", - [STAT_RESET_FAIL] = "Reset failed", - [STAT_NODEST] = "No destination is selected", - [STAT_MISMATCH] = "Data mismatch", - [STAT_NOACCESS] = "No access", - [STAT_BAD_CMD] = "Bad command", - [STAT_TOO_SHORT] = "Packet is too short", - [STAT_ERROFFS] = "Offset error", - [STAT_NOCODE] = "Source was not burned before", - [STAT_NO_LEEPROM] = "Large EEPROM was not found", - [STAT_NO_EEPROM] = "No EEPROM was found", - [STAT_WRITE_FAIL] = "Writing to device failed", - [STAT_FPGA_ERR] = "FPGA error", - [STAT_KEY_ERR] = "Bad Capabilities Key", - [STAT_NOCAPS_ERR] = "No matching capability", - [STAT_NOPWR_ERR] = "No power on USB connector", - [STAT_CAPS_FPGA_ERR] = "Setting of the capabilities while FPGA is loaded", - }; - if(status > sizeof(msgs)/sizeof(msgs[0])) - return "ERROR CODE TOO LARGE"; - if(!msgs[status]) - return "MISSING ERROR CODE"; - return msgs[status]; -} +enum eeprom_burn_state { + BURN_STATE_NONE = 0, + BURN_STATE_STARTED = 1, + BURN_STATE_ENDED = 2, + BURN_STATE_FAILED = 3, +}; const char *eeprom_type2str(int et) { @@ -92,6 +65,149 @@ const char *dev_dest2str(int dest) return msgs[dest]; }; +/* + * OP Codes: + * MSB of op signifies a reply from device + */ +#define MPP_RENUM 0x0B /* Trigger USB renumeration */ +#define MPP_EEPROM_SET 0x0D + +/* AB capabilities */ +#define MPP_CAPS_GET 0x0E +#define MPP_CAPS_GET_REPLY 0x8E +#define MPP_CAPS_SET 0x0F + +#define MPP_DEV_SEND_START 0x05 +#define MPP_DEV_SEND_SEG 0x07 +#define MPP_DEV_SEND_END 0x09 + +/* Astribank Status */ +#define MPP_STATUS_GET 0x11 +#define MPP_STATUS_GET_REPLY 0x91 +#define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */ + +/* Get extra vendor information */ +#define MPP_EXTRAINFO_GET 0x13 +#define MPP_EXTRAINFO_GET_REPLY 0x93 +#define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */ + +#define MPP_EEPROM_BLK_RD 0x27 +#define MPP_EEPROM_BLK_RD_REPLY 0xA7 + +#define MPP_SER_SEND 0x37 +#define MPP_SER_RECV 0xB7 + +#define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */ +#define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */ + +/* Twinstar */ +#define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */ +#define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */ +#define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */ +#define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */ +#define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */ +#define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */ +#define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */ + +CMD_DEF(MPP, STATUS_GET); + +CMD_DEF(MPP, STATUS_GET_REPLY, + uint8_t i2cs_data; + +#define STATUS_FPGA_LOADED(x) ((x) & 0x01) + uint8_t status; /* BIT(0) - FPGA is loaded */ + struct firmware_versions fw_versions; + ); + + +CMD_DEF(MPP, EEPROM_SET, + struct eeprom_table data; + ); + +CMD_DEF(MPP, CAPS_GET); + +CMD_DEF(MPP, CAPS_GET_REPLY, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, CAPS_SET, + struct eeprom_table data; + struct capabilities capabilities; + struct capkey key; + ); + +CMD_DEF(MPP, EXTRAINFO_GET); + +CMD_DEF(MPP, EXTRAINFO_GET_REPLY, + struct extrainfo info; + ); + +CMD_DEF(MPP, EXTRAINFO_SET, + struct extrainfo info; + ); + +CMD_DEF(MPP, RENUM); + +CMD_DEF(MPP, EEPROM_BLK_RD, + uint16_t offset; + uint16_t len; + ); + +CMD_DEF(MPP, EEPROM_BLK_RD_REPLY, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, DEV_SEND_START, + uint8_t dest; + char ihex_version[VERSION_LEN]; + ); + +CMD_DEF(MPP, DEV_SEND_END); + +CMD_DEF(MPP, DEV_SEND_SEG, + uint16_t offset; + uint8_t data[0]; + ); + +CMD_DEF(MPP, RESET); +CMD_DEF(MPP, HALF_RESET); + +CMD_DEF(MPP, SER_SEND, + uint8_t data[0]; + ); + +CMD_DEF(MPP, SER_RECV, + uint8_t data[0]; + ); + +CMD_DEF(MPP, TWS_WD_MODE_SET, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_WD_MODE_GET); +CMD_DEF(MPP, TWS_WD_MODE_GET_REPLY, + uint8_t wd_active; + ); + +CMD_DEF(MPP, TWS_PORT_SET, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PORT_GET); +CMD_DEF(MPP, TWS_PORT_GET_REPLY, + uint8_t portnum; + ); + +CMD_DEF(MPP, TWS_PWR_GET); +CMD_DEF(MPP, TWS_PWR_GET_REPLY, + uint8_t power; + ); + + union XTALK_PDATA(MPP) { MEMBER(MPP, STATUS_GET); MEMBER(MPP, STATUS_GET_REPLY); @@ -123,22 +239,44 @@ union XTALK_PDATA(MPP) { MEMBER(MPP, TWS_PWR_GET_REPLY); } PACKED members; -struct xtalk_protocol astribank_proto = { - .name = "ABNK", +/* + * Statuses + */ +#define STAT_OK 0x00 /* acknowledges previous command */ +#define STAT_FAIL 0x01 /* Last command failed */ +#define STAT_RESET_FAIL 0x02 /* reset failed */ +#define STAT_NODEST 0x03 /* No destination is selected */ +#define STAT_MISMATCH 0x04 /* Data mismatch */ +#define STAT_NOACCESS 0x05 /* No access */ +#define STAT_BAD_CMD 0x06 /* Bad command */ +#define STAT_TOO_SHORT 0x07 /* Packet is too short */ +#define STAT_ERROFFS 0x08 /* Offset error */ +#define STAT_NOCODE 0x09 /* Source was not burned before */ +#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ +#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ +#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ +#define STAT_FPGA_ERR 0x0D /* FPGA error */ +#define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */ +#define STAT_NOCAPS_ERR 0x0F /* No matching capability */ +#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ +#define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */ + +struct xtalk_protocol mpp_proto = { + .name = "MPP", .proto_version = 0x14, .commands = { CMD_SEND(MPP, STATUS_GET), - CMD_RECV(MPP, STATUS_GET_REPLY, NULL), + CMD_RECV(MPP, STATUS_GET_REPLY), CMD_SEND(MPP, EEPROM_SET), CMD_SEND(MPP, CAPS_GET), - CMD_RECV(MPP, CAPS_GET_REPLY, NULL), + CMD_RECV(MPP, CAPS_GET_REPLY), CMD_SEND(MPP, CAPS_SET), CMD_SEND(MPP, EXTRAINFO_GET), - CMD_RECV(MPP, EXTRAINFO_GET_REPLY, NULL), + CMD_RECV(MPP, EXTRAINFO_GET_REPLY), CMD_SEND(MPP, EXTRAINFO_SET), CMD_SEND(MPP, RENUM), CMD_SEND(MPP, EEPROM_BLK_RD), - CMD_RECV(MPP, EEPROM_BLK_RD_REPLY, NULL), + CMD_RECV(MPP, EEPROM_BLK_RD_REPLY), CMD_SEND(MPP, DEV_SEND_SEG), CMD_SEND(MPP, DEV_SEND_START), CMD_SEND(MPP, DEV_SEND_END), @@ -149,17 +287,85 @@ struct xtalk_protocol astribank_proto = { /* Twinstar */ CMD_SEND(MPP, TWS_WD_MODE_SET), CMD_SEND(MPP, TWS_WD_MODE_GET), - CMD_RECV(MPP, TWS_WD_MODE_GET_REPLY, NULL), + CMD_RECV(MPP, TWS_WD_MODE_GET_REPLY), CMD_SEND(MPP, TWS_PORT_SET), CMD_SEND(MPP, TWS_PORT_GET), - CMD_RECV(MPP, TWS_PORT_GET_REPLY, NULL), + CMD_RECV(MPP, TWS_PORT_GET_REPLY), CMD_SEND(MPP, TWS_PWR_GET), - CMD_RECV(MPP, TWS_PWR_GET_REPLY, NULL), + CMD_RECV(MPP, TWS_PWR_GET_REPLY), }, .ack_statuses = { + [STAT_OK] = "Acknowledges previous command", + [STAT_FAIL] = "Last command failed", + [STAT_RESET_FAIL] = "Reset failed", + [STAT_NODEST] = "No destination is selected", + [STAT_MISMATCH] = "Data mismatch", + [STAT_NOACCESS] = "No access", + [STAT_BAD_CMD] = "Bad command", + [STAT_TOO_SHORT] = "Packet is too short", + [STAT_ERROFFS] = "Offset error", + [STAT_NOCODE] = "Source was not burned before", + [STAT_NO_LEEPROM] = "Large EEPROM was not found", + [STAT_NO_EEPROM] = "No EEPROM was found", + [STAT_WRITE_FAIL] = "Writing to device failed", + [STAT_FPGA_ERR] = "FPGA error", + [STAT_KEY_ERR] = "Bad Capabilities Key", + [STAT_NOCAPS_ERR] = "No matching capability", + [STAT_NOPWR_ERR] = "No power on USB connector", + [STAT_CAPS_FPGA_ERR] = "Setting of the capabilities while FPGA is loaded", } }; +struct mpp_device { + struct xtalk_base *xtalk_base; + struct xtalk_sync *xtalk_sync; + enum eeprom_burn_state burn_state; + int eeprom_type; + int status; + struct firmware_versions fw_versions; +}; + +struct xusb_iface *xubs_iface_of_mpp(struct mpp_device *mpp) +{ + return xusb_iface_of_xtalk_base(mpp->xtalk_base); +} + +struct mpp_device *mpp_new(struct xusb_iface *iface) +{ + struct mpp_device *mpp_dev; + int ret; + + mpp_dev = calloc(sizeof(*mpp_dev), 1); + if (!mpp_dev) { + ERR("Out of memory\n"); + goto err; + } + mpp_dev->xtalk_base = xtalk_base_new_on_xusb(iface); + mpp_dev->xtalk_sync = xtalk_sync_new(mpp_dev->xtalk_base); + ret = xtalk_sync_set_protocol(mpp_dev->xtalk_sync, &mpp_proto); + if(ret < 0) { + ERR("MPP Protocol registration failed: %d\n", ret); + goto err; + } + return mpp_dev; +err: + if (mpp_dev) + free(mpp_dev); + return NULL; +} + +void mpp_delete(struct mpp_device *dev) +{ + xtalk_sync_delete(dev->xtalk_sync); + dev->xtalk_base = NULL; + free(dev); +} + +struct xtalk_sync *xtalk_of_mpp(const struct mpp_device *dev) +{ + return dev->xtalk_sync; +} + struct cmd_queue { struct cmd_queue *next; struct cmd_queue *prev; @@ -196,58 +402,68 @@ static int set_ihex_version(char *dst, const char *src) return 0; } +enum eeprom_type mpp_eeprom_type(struct mpp_device *mpp_dev) +{ + return mpp_dev->eeprom_type; +} + /* * Protocol Commands */ - -int mpp_status_query(struct astribank_device *astribank) +int mpp_status_query(struct mpp_device *mpp_dev) { - struct xtalk_command *cmd; - struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; - int ret; + struct xtalk_command *cmd; + struct xtalk_command *reply; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; + int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_STATUS_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, XTALK_OP(MPP, STATUS_GET), 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; } - astribank->eeprom_type = 0x3 & (CMD_FIELD(reply, MPP, STATUS_GET_REPLY, i2cs_data) >> 3); - astribank->status = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, status); - astribank->fw_versions = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, fw_versions); - DBG("EEPROM TYPE: %02x\n", astribank->eeprom_type); - DBG("FPGA Firmware: %s\n", (astribank->status & 0x1) ? "Loaded" : "Empty"); + mpp_dev->eeprom_type = 0x3 & (CMD_FIELD(reply, MPP, STATUS_GET_REPLY, i2cs_data) >> 3); + mpp_dev->status = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, status); + mpp_dev->fw_versions = CMD_FIELD(reply, MPP, STATUS_GET_REPLY, fw_versions); + DBG("EEPROM TYPE: %02x\n", mpp_dev->eeprom_type); + DBG("FPGA Firmware: %s\n", (mpp_dev->status & 0x1) ? "Loaded" : "Empty"); DBG("Firmware Versions: USB='%s' FPGA='%s' EEPROM='%s'\n", - astribank->fw_versions.usb, - astribank->fw_versions.fpga, - astribank->fw_versions.eeprom); + mpp_dev->fw_versions.usb, + mpp_dev->fw_versions.fpga, + mpp_dev->fw_versions.eeprom); free_command(reply); return ret; } -int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et) +int mpp_eeprom_set(struct mpp_device *mpp_dev, const struct eeprom_table *et) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_EEPROM_SET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_EEPROM_SET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } memcpy(&CMD_FIELD(cmd, MPP, EEPROM_SET, data), et, sizeof(*et)); - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -256,20 +472,23 @@ int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table return 0; } -int mpp_renumerate(struct astribank_device *astribank) +int mpp_renumerate(struct mpp_device *mpp_dev) { struct xtalk_command *cmd; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_RENUM, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_RENUM, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, NULL); + ret = process_command(xtalk_sync, cmd, NULL, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -277,24 +496,27 @@ int mpp_renumerate(struct astribank_device *astribank) return 0; } -int mpp_caps_get(struct astribank_device *astribank, +int mpp_caps_get(struct mpp_device *mpp_dev, struct eeprom_table *eeprom_table, struct capabilities *capabilities, struct capkey *key) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_CAPS_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_CAPS_GET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -317,27 +539,30 @@ int mpp_caps_get(struct astribank_device *astribank, return 0; } -int mpp_caps_set(struct astribank_device *astribank, +int mpp_caps_set(struct mpp_device *mpp_dev, const struct eeprom_table *eeprom_table, const struct capabilities *capabilities, const struct capkey *key) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_CAPS_SET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_CAPS_SET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, data), eeprom_table, sizeof(*eeprom_table)); memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, capabilities), capabilities, sizeof(*capabilities)); memcpy(&CMD_FIELD(cmd, MPP, CAPS_SET, key), key, sizeof(*key)); - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -346,21 +571,24 @@ int mpp_caps_set(struct astribank_device *astribank, return 0; } -int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info) +int mpp_extrainfo_get(struct mpp_device *mpp_dev, struct extrainfo *info) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_EXTRAINFO_GET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -383,22 +611,25 @@ int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info return 0; } -int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info) +int mpp_extrainfo_set(struct mpp_device *mpp_dev, const struct extrainfo *info) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_EXTRAINFO_SET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_EXTRAINFO_SET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } memcpy(&CMD_FIELD(cmd, MPP, EXTRAINFO_SET, info), info, sizeof(*info)); - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -407,24 +638,27 @@ int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo return 0; } -int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len) +int mpp_eeprom_blk_rd(struct mpp_device *mpp_dev, uint8_t *buf, uint16_t offset, uint16_t len) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; int size; DBG("len = %d, offset = %d\n", len, offset); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_EEPROM_BLK_RD, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_EEPROM_BLK_RD, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, len) = len; CMD_FIELD(cmd, MPP, EEPROM_BLK_RD, offset) = offset; - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); size = ret; @@ -443,24 +677,27 @@ out: return size; } -int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version) +int mpp_send_start(struct mpp_device *mpp_dev, int dest, const char *ihex_version) { struct xtalk_command *cmd; struct xtalk_command *reply = NULL; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret = 0; DBG("dest = %s ihex_version = '%s'\n", dev_dest2str(dest), ihex_version); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_START, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_DEV_SEND_START, 0)) == NULL) { ERR("new_command failed\n"); ret = -ENOMEM; goto out; } CMD_FIELD(cmd, MPP, DEV_SEND_START, dest) = dest; set_ihex_version(CMD_FIELD(cmd, MPP, DEV_SEND_START, ihex_version), ihex_version); - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); goto out; @@ -468,28 +705,31 @@ int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihe out: if(reply) free_command(reply); - astribank->burn_state = (ret == 0) + mpp_dev->burn_state = (ret > 0) ? BURN_STATE_STARTED : BURN_STATE_FAILED; return ret; } -int mpp_send_end(struct astribank_device *astribank) +int mpp_send_end(struct mpp_device *mpp_dev) { struct xtalk_command *cmd; struct xtalk_command *reply = NULL; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret = 0; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_END, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_DEV_SEND_END, 0)) == NULL) { ERR("new_command failed\n"); ret = -ENOMEM; goto out; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); goto out; @@ -497,28 +737,31 @@ int mpp_send_end(struct astribank_device *astribank) out: if(reply) free_command(reply); - astribank->burn_state = (ret == 0) + mpp_dev->burn_state = (ret > 0) ? BURN_STATE_ENDED : BURN_STATE_FAILED; return ret; } -int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len) +int mpp_send_seg(struct mpp_device *mpp_dev, const uint8_t *data, uint16_t offset, uint16_t len) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if(astribank->burn_state != BURN_STATE_STARTED) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if(mpp_dev->burn_state != BURN_STATE_STARTED) { ERR("Tried to send a segment while burn_state=%d\n", - astribank->burn_state); + mpp_dev->burn_state); return -EINVAL; } DBG("len = %d, offset = %d (0x%02X, 0x%02X)\n", len, offset, *data, *(data + 1)); - if((cmd = new_command(xtalk_dev, MPP_DEV_SEND_SEG, len)) == NULL) { + if((cmd = new_command(xtalk_base, MPP_DEV_SEND_SEG, len)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } @@ -538,7 +781,7 @@ int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16 fclose(fp); } #endif - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -547,21 +790,24 @@ int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16 return 0; } -int mpp_reset(struct astribank_device *astribank, int full_reset) +int mpp_reset(struct mpp_device *mpp_dev, int full_reset) { struct xtalk_command *cmd; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; int op = (full_reset) ? MPP_RESET: MPP_HALF_RESET; DBG("full = %s\n", (full_reset) ? "YES" : "NO"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, op, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, op, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, NULL); + ret = process_command(xtalk_sync, cmd, NULL, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -569,24 +815,27 @@ int mpp_reset(struct astribank_device *astribank, int full_reset) return 0; } -int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len) +int mpp_serial_cmd(struct mpp_device *mpp_dev, const uint8_t *in, uint8_t *out, uint16_t len) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; uint8_t *data; DBG("len=%d\n", len); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_SER_SEND, len)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_SER_SEND, len)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } data = CMD_FIELD(cmd, MPP, SER_SEND, data); memcpy(data, in, len); - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -598,7 +847,7 @@ int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_ return 0; } -int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status) +int mpps_card_info(struct mpp_device *mpp_dev, int unit, uint8_t *card_type, uint8_t *card_status) { /* * Serial commands must have equal send/receive size @@ -617,7 +866,7 @@ int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_t memset(&ci_recv, 0, sizeof(ci_recv)); ci_send.ser_op = SER_CARD_INFO_GET; ci_send.addr = (unit << 4); /* low nibble is subunit */ - ret = mpp_serial_cmd(astribank, + ret = mpp_serial_cmd(mpp_dev, (uint8_t *)&ci_send, (uint8_t *)&ci_recv, sizeof(struct card_info_command)); @@ -628,7 +877,7 @@ int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_t return 0; } -int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *fpga_configuration, uint8_t *status) +int mpps_stat(struct mpp_device *mpp_dev, int unit, uint8_t *fpga_configuration, uint8_t *status) { /* * Serial commands must have equal send/receive size @@ -645,7 +894,7 @@ int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *fpga_config memset(&fs_send, 0, sizeof(fs_send)); memset(&fs_recv, 0, sizeof(fs_recv)); fs_send.ser_op = SER_STAT_GET; - ret = mpp_serial_cmd(astribank, + ret = mpp_serial_cmd(mpp_dev, (uint8_t *)&fs_send, (uint8_t *)&fs_recv, sizeof(struct fpga_stat_command)); @@ -656,21 +905,24 @@ int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *fpga_config return 0; } -int mpp_tws_watchdog(struct astribank_device *astribank) +int mpp_tws_watchdog(struct mpp_device *mpp_dev) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_TWS_WD_MODE_GET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -681,22 +933,25 @@ int mpp_tws_watchdog(struct astribank_device *astribank) return ret == 1; } -int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes) +int mpp_tws_setwatchdog(struct mpp_device *mpp_dev, int yes) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("%s\n", (yes) ? "YES" : "NO"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_TWS_WD_MODE_SET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_TWS_WD_MODE_SET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } CMD_FIELD(cmd, MPP, TWS_WD_MODE_SET, wd_active) = (yes) ? 1 : 0; - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -705,21 +960,24 @@ int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes) return 0; } -int mpp_tws_powerstate(struct astribank_device *astribank) +int mpp_tws_powerstate(struct mpp_device *mpp_dev) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_TWS_PWR_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_TWS_PWR_GET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -730,21 +988,24 @@ int mpp_tws_powerstate(struct astribank_device *astribank) return ret; } -int mpp_tws_portnum(struct astribank_device *astribank) +int mpp_tws_portnum(struct mpp_device *mpp_dev) { struct xtalk_command *cmd; struct xtalk_command *reply; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; - if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_GET, 0)) == NULL) { + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; + if((cmd = new_command(xtalk_base, MPP_TWS_PORT_GET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } - ret = process_command(xtalk_dev, cmd, &reply); + ret = process_command(xtalk_sync, cmd, &reply, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -755,25 +1016,28 @@ int mpp_tws_portnum(struct astribank_device *astribank) return ret; } -int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum) +int mpp_tws_setportnum(struct mpp_device *mpp_dev, uint8_t portnum) { struct xtalk_command *cmd; - struct xtalk_device *xtalk_dev; + struct xtalk_sync *xtalk_sync; + struct xtalk_base *xtalk_base; + uint16_t tx_seq; int ret; DBG("\n"); - assert(astribank != NULL); - xtalk_dev = astribank->xtalk_dev; + assert(mpp_dev != NULL); + xtalk_sync = mpp_dev->xtalk_sync; + xtalk_base = mpp_dev->xtalk_base; if(portnum >= 2) { ERR("Invalid portnum (%d)\n", portnum); return -EINVAL; } - if((cmd = new_command(xtalk_dev, MPP_TWS_PORT_SET, 0)) == NULL) { + if((cmd = new_command(xtalk_base, MPP_TWS_PORT_SET, 0)) == NULL) { ERR("new_command failed\n"); return -ENOMEM; } CMD_FIELD(cmd, MPP, TWS_PORT_SET, portnum) = portnum; - ret = process_command(xtalk_dev, cmd, NULL); + ret = process_command(xtalk_sync, cmd, NULL, &tx_seq); if(ret < 0) { ERR("process_command failed: %d\n", ret); return ret; @@ -781,98 +1045,18 @@ int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum) return 0; } -/* Adapters for xusb ops */ -static inline int xusb_close_func(void *priv) -{ - return xusb_close((struct xusb *)priv); -} - -static inline int xusb_send_func(void *priv, void *data, size_t len, int timeout) -{ - return xusb_send((struct xusb *)priv, data, len, timeout); -} - -static inline int xusb_recv_func(void *priv, void *data, size_t maxlen, int timeout) -{ - return xusb_recv((struct xusb *)priv, data, maxlen, timeout); -} - - -static struct xtalk_ops xusb_ops = { - .send_func = xusb_send_func, - .recv_func = xusb_recv_func, - .close_func = xusb_close_func, -}; - -/* - * Wrappers - */ - -struct astribank_device *mpp_init(const char devpath[], int iface_num) -{ - struct astribank_device *astribank = NULL; - struct xtalk_device *xtalk_dev = NULL; - struct xusb *xusb = NULL; - int packet_size; - int ret; - - DBG("devpath='%s' iface_num=%d\n", devpath, iface_num); - if((astribank = astribank_open(devpath, iface_num)) == NULL) { - ERR("Opening astribank failed\n"); - goto err; - } - xusb = astribank->xusb; - packet_size = xusb_packet_size(xusb); - if((xtalk_dev = xtalk_new(&xusb_ops, packet_size, xusb)) == NULL) { - ERR("Allocating new XTALK device failed\n"); - goto err; - } - astribank->xtalk_dev = xtalk_dev; - ret = xtalk_set_protocol(xtalk_dev, &astribank_proto); - if(ret < 0) { - ERR("MPP Protocol registration failed: %d\n", ret); - goto err; - } - ret = xtalk_proto_query(xtalk_dev); - if(ret < 0) { - ERR("Protocol handshake failed: %d\n", ret); - goto err; - } - ret = mpp_status_query(astribank); - if(ret < 0) { - ERR("Status query failed: %d\n", ret); - goto err; - } - return astribank; - -err: - if (astribank) { - astribank_close(astribank, 0); - astribank = NULL; - } - if(xtalk_dev) { - xtalk_delete(xtalk_dev); - xtalk_dev = NULL; - } - return NULL; -} - -void mpp_exit(struct astribank_device *astribank) -{ - DBG("\n"); - astribank_close(astribank, 0); -} - /* * data structures */ void show_eeprom(const struct eeprom_table *eprm, FILE *fp) { - int rmajor = (eprm->release >> 8) & 0xFF; - int rminor = eprm->release & 0xFF;; + int rmajor; + int rminor; char buf[BUFSIZ]; + rmajor = (eprm->release >> 8) & 0xFF; + rminor = eprm->release & 0xFF;; memset(buf, 0, LABEL_SIZE + 1); memcpy(buf, eprm->label, LABEL_SIZE); fprintf(fp, "EEPROM: %-15s: 0x%02X\n", "Source", eprm->source); @@ -894,18 +1078,18 @@ void show_capabilities(const struct capabilities *capabilities, FILE *fp) (CAP_EXTRA_TWINSTAR(capabilities)) ? "Yes" : "No"); } -void show_astribank_status(struct astribank_device *astribank, FILE *fp) +void show_astribank_status(struct mpp_device *mpp_dev, FILE *fp) { char version_buf[BUFSIZ]; - int is_loaded = STATUS_FPGA_LOADED(astribank->status); + int is_loaded = STATUS_FPGA_LOADED(mpp_dev->status); fprintf(fp, "Astribank: EEPROM : %s\n", - eeprom_type2str(astribank->eeprom_type)); + eeprom_type2str(mpp_dev->eeprom_type)); fprintf(fp, "Astribank: FPGA status : %s\n", is_loaded ? "Loaded" : "Empty"); if(is_loaded) { memset(version_buf, 0, sizeof(version_buf)); - memcpy(version_buf, astribank->fw_versions.fpga, VERSION_LEN); + memcpy(version_buf, mpp_dev->fw_versions.fpga, VERSION_LEN); fprintf(fp, "Astribank: FPGA version: %s\n", version_buf); } @@ -920,26 +1104,22 @@ void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp) fprintf(fp, "Extrainfo: : '%s'\n", buf); } -int twinstar_show(struct astribank_device *astribank, FILE *fp) +int twinstar_show(struct mpp_device *mpp, FILE *fp) { int watchdog; int powerstate; int portnum; int i; - if(!astribank_has_twinstar(astribank)) { - fprintf(fp, "TwinStar: NO\n"); - return 0; - } - if((watchdog = mpp_tws_watchdog(astribank)) < 0) { + if((watchdog = mpp_tws_watchdog(mpp)) < 0) { ERR("Failed getting TwinStar information\n"); return watchdog; } - if((powerstate = mpp_tws_powerstate(astribank)) < 0) { + if((powerstate = mpp_tws_powerstate(mpp)) < 0) { ERR("Failed getting TwinStar powerstate\n"); return powerstate; } - if((portnum = mpp_tws_portnum(astribank)) < 0) { + if((portnum = mpp_tws_portnum(mpp)) < 0) { ERR("Failed getting TwinStar portnum\n"); return portnum; } @@ -954,3 +1134,56 @@ int twinstar_show(struct astribank_device *astribank, FILE *fp) } return 0; } + +int show_hardware(struct mpp_device *mpp_dev) +{ + int ret; + struct eeprom_table eeprom_table; + struct capabilities capabilities; + struct extrainfo extrainfo; + + ret = mpp_caps_get(mpp_dev, &eeprom_table, &capabilities, NULL); + if(ret < 0) + return ret; + show_eeprom(&eeprom_table, stdout); + show_astribank_status(mpp_dev, stdout); + if(mpp_dev->eeprom_type == EEPROM_TYPE_LARGE) { + show_capabilities(&capabilities, stdout); + if(STATUS_FPGA_LOADED(mpp_dev->status)) { + uint8_t unit; + uint8_t card_status; + uint8_t card_type; + uint8_t fpga_configuration; + uint8_t status; + + for(unit = 0; unit < 5; unit++) { + ret = mpps_card_info(mpp_dev, unit, &card_type, &card_status); + if(ret < 0) + return ret; + printf("CARD %d: type=%x.%x %s\n", unit, + ((card_type >> 4) & 0xF), (card_type & 0xF), + ((card_status & 0x1) ? "PIC" : "NOPIC")); + } + ret = mpps_stat(mpp_dev, unit, &fpga_configuration, &status); + if (ret < 0) + return ret; + printf("FPGA: %-17s: %d\n", "Configuration num", fpga_configuration); + printf("FPGA: %-17s: %s\n", "Watchdog Timer", + (SER_STAT_WATCHDOG_READY(status)) ? "ready" : "expired"); + printf("FPGA: %-17s: %s\n", "XPD Alive", + (SER_STAT_XPD_ALIVE(status)) ? "yes" : "no"); + } + ret = mpp_extrainfo_get(mpp_dev, &extrainfo); + if(ret < 0) + return ret; + show_extrainfo(&extrainfo, stdout); + if(CAP_EXTRA_TWINSTAR(&capabilities)) { + if ((eeprom_table.product & 0xFFF0) != 0x1160) + printf("TwinStar: NO\n"); + else + twinstar_show(mpp_dev, stdout); + } + } + return 0; +} + diff --git a/xpp/mpptalk.h b/xpp/mpptalk.h index 49db037..9931f56 100644 --- a/xpp/mpptalk.h +++ b/xpp/mpptalk.h @@ -1,5 +1,5 @@ -#ifndef MPP_FUNCS_H -#define MPP_FUNCS_H +#ifndef MPPTALK_H +#define MPPTALK_H /* * Written by Oron Peled * Copyright (C) 2008, Xorcom @@ -22,64 +22,152 @@ * */ -#include -#include - -#include "mpp.h" -#include "astribank_usb.h" - -struct astribank_device; -struct eeprom_table; -struct extrainfo; -struct capabilities; -struct capkey; - -#define TIMEOUT 6000 - -/* high-level */ -struct astribank_device *mpp_init(const char devpath[], int iface_num); -void mpp_exit(struct astribank_device *astribank); -int mpp_proto_query(struct astribank_device *astribank); -int mpp_status_query(struct astribank_device *astribank); -int mpp_eeprom_set(struct astribank_device *astribank, const struct eeprom_table *et); -int mpp_renumerate(struct astribank_device *astribank); -int mpp_caps_get(struct astribank_device *astribank, - struct eeprom_table *et, - struct capabilities *cap, - struct capkey *key); -int mpp_caps_set(struct astribank_device *astribank, - const struct eeprom_table *eeprom_table, - const struct capabilities *capabilities, - const struct capkey *key); -int mpp_extrainfo_get(struct astribank_device *astribank, struct extrainfo *info); -int mpp_extrainfo_set(struct astribank_device *astribank, const struct extrainfo *info); -int mpp_eeprom_blk_rd(struct astribank_device *astribank, uint8_t *buf, uint16_t offset, uint16_t len); -int mpp_send_start(struct astribank_device *astribank, int dest, const char *ihex_version); -int mpp_send_end(struct astribank_device *astribank); -int mpp_send_seg(struct astribank_device *astribank, const uint8_t *data, uint16_t offset, uint16_t len); -int mpp_reset(struct astribank_device *astribank, int full_reset); -int mpp_serial_cmd(struct astribank_device *astribank, const uint8_t *in, uint8_t *out, uint16_t len); -void show_eeprom(const struct eeprom_table *eprm, FILE *fp); -void show_capabilities(const struct capabilities *capabilities, FILE *fp); -void show_astribank_status(struct astribank_device *astribank, FILE *fp); -void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp); -int twinstar_show(struct astribank_device *astribank, FILE *fp); +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ /* - * Serial commands to FPGA + * MPPTALK - Example XTALK dialect */ -int mpps_card_info(struct astribank_device *astribank, int unit, uint8_t *card_type, uint8_t *card_status); -int mpps_stat(struct astribank_device *astribank, int unit, uint8_t *maincard_version, uint8_t *status); + +#include +#include + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#else +#define PACKED +#endif + +/*---------------- Common types --------------------*/ + +/* + * The eeprom_table is common to all eeprom types. + */ +#define LABEL_SIZE 8 +struct eeprom_table { + uint8_t source; /* C0 - small eeprom, C2 - large eeprom */ + uint16_t vendor; + uint16_t product; + uint16_t release; /* BCD encoded release */ + uint8_t config_byte; /* Must be 0 */ + uint8_t label[LABEL_SIZE]; +} PACKED; + +#define VERSION_LEN 6 +struct firmware_versions { + char usb[VERSION_LEN]; + char fpga[VERSION_LEN]; + char eeprom[VERSION_LEN]; +} PACKED; + +struct capabilities { + uint8_t ports_fxs; + uint8_t ports_fxo; + uint8_t ports_bri; + uint8_t ports_pri; + uint8_t extra_features; /* BIT(0) - TwinStar */ + uint8_t ports_echo; + uint8_t reserved[2]; + uint32_t timestamp; +} PACKED; + +#define CAP_EXTRA_TWINSTAR(c) ((c)->extra_features & 0x01) +#define CAP_EXTRA_TWINSTAR_SET(c) do {(c)->extra_features |= 0x01;} while (0) +#define CAP_EXTRA_TWINSTAR_CLR(c) do {(c)->extra_features &= ~0x01;} while (0) + +#define KEYSIZE 16 +struct capkey { + uint8_t k[KEYSIZE]; +} PACKED; + +#define EXTRAINFO_SIZE 24 +struct extrainfo { + char text[EXTRAINFO_SIZE]; +} PACKED; + +struct mpp_header { + uint16_t len; + uint16_t seq; + uint8_t op; /* MSB: 0 - to device, 1 - from device */ +} PACKED; + +enum mpp_ser_op { + SER_CARD_INFO_GET = 0x1, + SER_STAT_GET = 0x3, +/* Status bits */ +#define SER_STAT_WATCHDOG_READY(s) ((s) & 0x01) +#define SER_STAT_XPD_ALIVE(s) ((s) & 0x02) +}; + +/* EEPROM_QUERY: i2cs(ID1, ID0) */ +enum eeprom_type { + EEPROM_TYPE_NONE = 0, + EEPROM_TYPE_SMALL = 1, + EEPROM_TYPE_LARGE = 2, + EEPROM_TYPE_UNUSED = 3, +}; + +enum dev_dest { + DEST_NONE = 0x00, + DEST_FPGA = 0x01, + DEST_EEPROM = 0x02, +}; + + +/*---------------- PROTOCOL ------------------------*/ +/* API */ +struct mpp_device; + +struct mpp_device *mpp_new(struct xusb_iface *iface); +void mpp_delete(struct mpp_device *dev); +struct xusb_iface *xubs_iface_of_mpp(struct mpp_device *mpp); +int mpp_status_query(struct mpp_device *mpp_dev); + +enum eeprom_type mpp_eeprom_type(struct mpp_device *mpp_dev); + +void show_eeprom(const struct eeprom_table *eprm, FILE *fp); +void show_capabilities(const struct capabilities *capabilities, FILE *fp); +void show_astribank_status(struct mpp_device *mpp_dev, FILE *fp); +void show_extrainfo(const struct extrainfo *extrainfo, FILE *fp); +int twinstar_show(struct mpp_device *mpp, FILE *fp); +int show_hardware(struct mpp_device *mpp_dev); + +int mpp_renumerate(struct mpp_device *mpp_dev); +int mpp_send_start(struct mpp_device *mpp_dev, int dest, const char *ihex_version); +int mpp_send_end(struct mpp_device *mpp_dev); +int mpp_send_seg(struct mpp_device *mpp_dev, const uint8_t *data, uint16_t offset, uint16_t len); +int mpp_reset(struct mpp_device *mpp_dev, int full_reset); + +int mpp_caps_get(struct mpp_device *mpp_dev, + struct eeprom_table *eeprom_table, + struct capabilities *capabilities, + struct capkey *key); +int mpp_caps_set(struct mpp_device *mpp_dev, + const struct eeprom_table *eeprom_table, + const struct capabilities *capabilities, + const struct capkey *key); + +/* + * serial sub-protocol to FPGA + */ +int mpps_card_info(struct mpp_device *mpp, int unit, uint8_t *card_type, uint8_t *card_status); +int mpps_stat(struct mpp_device *mpp, int unit, uint8_t *maincard_version, uint8_t *status); /* * Twinstar */ -int mpp_tws_watchdog(struct astribank_device *astribank); -int mpp_tws_setwatchdog(struct astribank_device *astribank, int yes); -int mpp_tws_powerstate(struct astribank_device *astribank); -int mpp_tws_portnum(struct astribank_device *astribank); -int mpp_tws_setportnum(struct astribank_device *astribank, uint8_t portnum); +int mpp_tws_watchdog(struct mpp_device *mpp); +int mpp_tws_setwatchdog(struct mpp_device *mpp, int yes); +int mpp_tws_powerstate(struct mpp_device *mpp); +int mpp_tws_portnum(struct mpp_device *mpp); +int mpp_tws_setportnum(struct mpp_device *mpp, uint8_t portnum); const char *dev_dest2str(int dest); -#endif /* MPP_FUNCS_H */ +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* MPPTALK_H */ diff --git a/xpp/mpptalk_defs.h b/xpp/mpptalk_defs.h deleted file mode 100644 index bc0b83b..0000000 --- a/xpp/mpptalk_defs.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef MPPTALK_DEFS_H -#define MPPTALK_DEFS_H -/* - * Written by Oron Peled - * Copyright (C) 2008,2009,2010 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 -/* - * MPP - Managment Processor Protocol definitions - */ - -/* - * OP Codes: - * MSB of op signifies a reply from device - */ -#define MPP_RENUM 0x0B /* Trigger USB renumeration */ -#define MPP_EEPROM_SET 0x0D - -/* AB capabilities */ -#define MPP_CAPS_GET 0x0E -#define MPP_CAPS_GET_REPLY 0x8E -#define MPP_CAPS_SET 0x0F - -#define MPP_DEV_SEND_START 0x05 -#define MPP_DEV_SEND_SEG 0x07 -#define MPP_DEV_SEND_END 0x09 - -/* Astribank Status */ -#define MPP_STATUS_GET 0x11 -#define MPP_STATUS_GET_REPLY 0x91 -#define MPP_STATUS_GET_REPLY_V13 0x91 /* backward compat */ - -/* Get extra vendor information */ -#define MPP_EXTRAINFO_GET 0x13 -#define MPP_EXTRAINFO_GET_REPLY 0x93 -#define MPP_EXTRAINFO_SET 0x15 /* Set extra vendor information */ - -#define MPP_EEPROM_BLK_RD 0x27 -#define MPP_EEPROM_BLK_RD_REPLY 0xA7 - -#define MPP_SER_SEND 0x37 -#define MPP_SER_RECV 0xB7 - -#define MPP_RESET 0x45 /* Reset both FPGA and USB firmwares */ -#define MPP_HALF_RESET 0x47 /* Reset only FPGA firmware */ - -/* Twinstar */ -#define MPP_TWS_WD_MODE_SET 0x31 /* Set watchdog off/on guard */ -#define MPP_TWS_WD_MODE_GET 0x32 /* Current watchdog mode */ -#define MPP_TWS_WD_MODE_GET_REPLY 0xB2 /* Current watchdog mode */ -#define MPP_TWS_PORT_SET 0x34 /* USB-[0/1] */ -#define MPP_TWS_PORT_GET 0x35 /* USB-[0/1] */ -#define MPP_TWS_PORT_GET_REPLY 0xB5 /* USB-[0/1] */ -#define MPP_TWS_PWR_GET 0x36 /* Power: bits -> USB ports */ -#define MPP_TWS_PWR_GET_REPLY 0xB6 /* Power: bits -> USB ports */ - -/* - * Statuses - */ -#define STAT_OK 0x00 /* acknowledges previous command */ -#define STAT_FAIL 0x01 /* Last command failed */ -#define STAT_RESET_FAIL 0x02 /* reset failed */ -#define STAT_NODEST 0x03 /* No destination is selected */ -#define STAT_MISMATCH 0x04 /* Data mismatch */ -#define STAT_NOACCESS 0x05 /* No access */ -#define STAT_BAD_CMD 0x06 /* Bad command */ -#define STAT_TOO_SHORT 0x07 /* Packet is too short */ -#define STAT_ERROFFS 0x08 /* Offset error */ -#define STAT_NOCODE 0x09 /* Source was not burned before */ -#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ -#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ -#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ -#define STAT_FPGA_ERR 0x0D /* FPGA error */ -#define STAT_KEY_ERR 0x0E /* Bad Capabilities Key */ -#define STAT_NOCAPS_ERR 0x0F /* No matching capability */ -#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ -#define STAT_CAPS_FPGA_ERR 0x11 /* Setting of the capabilities while FPGA is loaded */ - -/* EEPROM_QUERY: i2cs(ID1, ID0) */ -enum eeprom_type { - EEPROM_TYPE_NONE = 0, - EEPROM_TYPE_SMALL = 1, - EEPROM_TYPE_LARGE = 2, - EEPROM_TYPE_UNUSED = 3, -}; - -enum dev_dest { - DEST_NONE = 0x00, - DEST_FPGA = 0x01, - DEST_EEPROM = 0x02, -}; - -#define EXTRAINFO_SIZE 24 - -#endif /* MPPTALK_DEFS_H */ diff --git a/xpp/pic_loader.c b/xpp/pic_loader.c index c6ed3f1..6a387fe 100644 --- a/xpp/pic_loader.c +++ b/xpp/pic_loader.c @@ -25,12 +25,12 @@ #include #include #include +#include +#include #include "hexfile.h" #include "pic_loader.h" -#include -#include -#define DBG_MASK 0x03 +#define DBG_MASK 0x20 #define MAX_HEX_LINES 10000 #define TIMEOUT 500 @@ -57,7 +57,7 @@ struct xpp_packet_header { } d; } PACKED; -int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len) +int send_picline(struct astribank *ab, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len) { int recv_answer = 0; char buf[PACKET_SIZE]; @@ -65,7 +65,7 @@ int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic int pack_len; int ret; - assert(astribank != NULL); + assert(ab != NULL); pack_len = data_len + sizeof(phead->header) + sizeof(phead->d.pic_packet.pic_header); phead->header.len = pack_len; phead->header.op = PIC_REQ_XOP; @@ -90,14 +90,14 @@ int send_picline(struct astribank_device *astribank, uint8_t card_type, enum pic DBG("PICLINE: pack_len=%d pcmd=%d\n", pack_len, pcmd); dump_packet(LOG_DEBUG, DBG_MASK, "dump:picline[W]", (char *)phead, pack_len); - ret = xusb_send(astribank->xusb, buf, pack_len, TIMEOUT); + ret = astribank_send(ab, 0, buf, pack_len, TIMEOUT); if(ret < 0) { - ERR("xusb_send failed: %d\n", ret); + ERR("astribank_send failed: %d\n", ret); return ret; } - DBG("xusb_send: Written %d bytes\n", ret); + DBG("astribank_send: Written %d bytes\n", ret); if (recv_answer) { - ret = xusb_recv(astribank->xusb, buf, sizeof(buf), TIMEOUT); + ret = astribank_recv(ab, 0, buf, sizeof(buf), TIMEOUT); if(ret <= 0) { ERR("No USB packs to read\n"); return ret; @@ -172,7 +172,7 @@ static const char *pic_basename(const char *fname, uint8_t *card_type) /* * Returns: true on success, false on failure */ -static int pic_burn(struct astribank_device *astribank, const struct hexdata *hexdata) +static int pic_burn(struct astribank *ab, const struct hexdata *hexdata) { const char *v = hexdata->version_info; const char *basename; @@ -182,18 +182,21 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he int ret; unsigned int i; const char *devstr; + const struct xusb_device *xusb; v = (v[0]) ? v : "Unknown"; - assert(astribank != NULL); + assert(ab != NULL); assert(hexdata != NULL); - devstr = xusb_devpath(astribank->xusb); - if(!astribank->is_usb2) { + xusb = xusb_dev_of_astribank(ab); + devstr = xusb_devpath(xusb); + i = xusb_packet_size(xusb); + if(i != 512) { ERR("%s: Skip PIC burning (not USB2)\n", devstr); return 0; } INFO("%s [%s]: Loading PIC Firmware: %s (version %s)\n", devstr, - xusb_serial(astribank->xusb), + xusb_serial(xusb), hexdata->fname, hexdata->version_info); basename = pic_basename(hexdata->fname, &card_type); @@ -209,10 +212,10 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he for(i = 2; i; i--) { char buf[PACKET_SIZE]; - if(xusb_recv(astribank->xusb, buf, sizeof(buf), 1) <= 0) + if (astribank_recv(ab, 0, buf, sizeof(buf), TIMEOUT) <= 0) break; } - if((ret = send_picline(astribank, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) { + if((ret = send_picline(ab, card_type, PIC_START_FLAG, 0, NULL, 0)) != 0) { perror("Failed sending start hexline"); return 0; } @@ -233,7 +236,7 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he } data = hexline->d.content.tt_data.data; check_sum ^= data[0] ^ data[1] ^ data[2]; - ret = send_picline(astribank, card_type, PIC_DATA_FLAG, + ret = send_picline(ab, card_type, PIC_DATA_FLAG, hexline->d.content.header.offset, data, len); if(ret) { perror("Failed sending data hexline"); @@ -247,7 +250,7 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he return 0; } } - if((ret = send_picline(astribank, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) { + if((ret = send_picline(ab, card_type, PIC_END_FLAG, 0, &check_sum, 1)) != 0) { perror("Failed sending end hexline"); return 0; } @@ -255,12 +258,12 @@ static int pic_burn(struct astribank_device *astribank, const struct hexdata *he return 1; } -int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]) +int load_pic(struct astribank *ab, int numfiles, char *filelist[]) { int i; const char *devstr; - devstr = xusb_devpath(astribank->xusb); + devstr = xusb_devpath(xusb_dev_of_astribank(ab)); DBG("%s: Loading %d PIC files...\n", devstr, numfiles); for(i = 0; i < numfiles; i++) { struct hexdata *picdata; @@ -271,13 +274,13 @@ int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]) perror(curr); return -errno; } - if(!pic_burn(astribank, picdata)) { + if(!pic_burn(ab, picdata)) { ERR("%s: PIC %s burning failed\n", devstr, curr); return -ENODEV; } free_hexdata(picdata); } - if((i = send_picline(astribank, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) { + if((i = send_picline(ab, 0, PIC_ENDS_FLAG, 0, NULL, 0)) != 0) { ERR("%s: PIC end burning failed\n", devstr); return -ENODEV; } diff --git a/xpp/pic_loader.h b/xpp/pic_loader.h index f871bca..3f49040 100644 --- a/xpp/pic_loader.h +++ b/xpp/pic_loader.h @@ -23,7 +23,7 @@ */ #include -#include "astribank_usb.h" +#include "astribank.h" /* * Astribank PIC loading @@ -39,8 +39,8 @@ enum pic_command { #define PIC_PACK_LEN 0x0B #define PIC_LINE_LEN 0x03 -int send_picline(struct astribank_device *astribank, uint8_t card_type, +int send_picline(struct astribank *astribank, uint8_t card_type, enum pic_command pcmd, int offs, uint8_t *data, int data_len); -int load_pic(struct astribank_device *astribank, int numfiles, char *filelist[]); +int load_pic(struct astribank *astribank, int numfiles, char *filelist[]); #endif /* PIC_LOADER_H */ diff --git a/xpp/xtalk/Makefile.am b/xpp/xtalk/Makefile.am index e26e6b1..f719627 100644 --- a/xpp/xtalk/Makefile.am +++ b/xpp/xtalk/Makefile.am @@ -19,12 +19,7 @@ noinst_PROGRAMS = xlist_test xusb_test xusb_test_bypath xtalk_test xtalk_raw_te sbin_PROGRAMS = xtalk_send noinst_LTLIBRARIES = libxtalk.la dist_noinst_HEADERS = \ - debug.h \ - xlist.h \ - xtalk.h \ xtalk_base.h \ - xtalk_defs.h \ - xusb.h \ xusb_common.h \ include/xtalk/proto_raw.h \ include/xtalk/api_defs.h \ diff --git a/xpp/xtalk/xtalk.c b/xpp/xtalk/xtalk.c deleted file mode 100644 index ee2b520..0000000 --- a/xpp/xtalk/xtalk.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * Written by Oron Peled - * Copyright (C) 2009, 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 -#include -#include -#include -#include -#include -#include -#include - -#define DBG_MASK 0x02 - -#define TIMEOUT 6000 - -/* - * Base XTALK device. A pointer to this struct - * should be included in the struct representing - * the dialect. - */ -struct xtalk_device { - void *transport_priv; /* e.g: struct xusb */ - struct xtalk_ops ops; - struct xtalk_protocol xproto; - uint8_t xtalk_proto_version; - uint8_t status; - size_t packet_size; - uint16_t tx_sequenceno; -}; - -CMD_DEF(XTALK, ACK, - uint8_t stat; - ); - -CMD_DEF(XTALK, PROTO_GET, - uint8_t proto_version; - uint8_t reserved; - ); - -CMD_DEF(XTALK, PROTO_GET_REPLY, - uint8_t proto_version; - uint8_t reserved; - ); - -union XTALK_PDATA(XTALK) { - MEMBER(XTALK, ACK); - MEMBER(XTALK, PROTO_GET); - MEMBER(XTALK, PROTO_GET_REPLY); -} PACKED members; - -struct xtalk_protocol xtalk_base = { - .name = "XTALK", - .proto_version = 0, - .commands = { - CMD_RECV(XTALK, ACK, NULL), - CMD_SEND(XTALK, PROTO_GET), - CMD_RECV(XTALK, PROTO_GET_REPLY, NULL), - }, - .ack_statuses = { - ACK_STAT(OK, "Acknowledges previous command"), - ACK_STAT(FAIL, "Last command failed"), - ACK_STAT(RESET_FAIL, "reset failed"), - ACK_STAT(NODEST, "No destination is selected"), - ACK_STAT(MISMATCH, "Data mismatch"), - ACK_STAT(NOACCESS, "No access"), - ACK_STAT(BAD_CMD, "Bad command"), - ACK_STAT(TOO_SHORT, "Packet is too short"), - ACK_STAT(ERROFFS, "Offset error (not used)"), - ACK_STAT(NO_LEEPROM, "Large EEPROM was not found"), - ACK_STAT(NO_EEPROM, "No EEPROM was found"), - ACK_STAT(WRITE_FAIL, "Writing to device failed"), - ACK_STAT(NOPWR_ERR, "No power on USB connector"), - } -}; - -void free_command(struct xtalk_command *cmd) -{ - if (!cmd) - return; - memset(cmd, 0, cmd->header.len); - free(cmd); -} - -static const struct xtalk_command_desc *get_command_desc( - const struct xtalk_protocol *xproto, uint8_t op) -{ - const struct xtalk_command_desc *desc; - - if (!xproto) - return NULL; - desc = &xproto->commands[op]; - if (!desc->name) - return NULL; -#if 0 - DBG("%s version=%d, op=0x%X (%s)\n", - xproto->name, xproto->proto_version, - op, desc->name); -#endif - return desc; -} - -static const char *ack_status_msg(const struct xtalk_protocol *xproto, - uint8_t status) -{ - const char *ack_status; - - if (!xproto) - return NULL; - ack_status = xproto->ack_statuses[status]; - DBG("%s status=0x%X (%s)\n", xproto->name, status, ack_status); - return ack_status; -} - -int xtalk_set_protocol(struct xtalk_device *xtalk_dev, - const struct xtalk_protocol *xproto) -{ - const char *protoname = (xproto) ? xproto->name : "GLOBAL"; - int i; - - DBG("%s\n", protoname); - memset(&xtalk_dev->xproto, 0, sizeof(xtalk_dev->xproto)); - for (i = 0; i < MAX_OPS; i++) { - const struct xtalk_command_desc *desc; - - desc = get_command_desc(xproto, i); - if (desc) { - if (!IS_PRIVATE_OP(i)) { - ERR("Bad op=0x%X " - "(should be in the range [0x%X-0x%X]\n", - i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); - return -EINVAL; - } - xtalk_dev->xproto.commands[i] = *desc; - DBG("private: op=0x%X (%s)\n", i, desc->name); - } else { - if (!IS_PRIVATE_OP(i)) { - const char *name; - - xtalk_dev->xproto.commands[i] = - xtalk_base.commands[i]; - name = xtalk_dev->xproto.commands[i].name; - if (name) - DBG("global: op=0x%X (%s)\n", i, name); - } - } - } - for (i = 0; i < MAX_STATUS; i++) { - const char *stat_msg; - - stat_msg = (xproto) ? xproto->ack_statuses[i] : NULL; - if (stat_msg) { - if (!IS_PRIVATE_OP(i)) { - ERR("Bad status=0x%X " - "(should be in the range [0x%X-0x%X]\n", - i, PRIVATE_OP_FIRST, PRIVATE_OP_LAST); - return -EINVAL; - } - xtalk_dev->xproto.ack_statuses[i] = stat_msg; - DBG("private: status=0x%X (%s)\n", i, stat_msg); - } else { - if (!IS_PRIVATE_OP(i)) { - const char *stat_msg; - - xtalk_dev->xproto.ack_statuses[i] = - xtalk_base.ack_statuses[i]; - stat_msg = xtalk_dev->xproto.ack_statuses[i]; - if (stat_msg) - DBG("global: status=0x%X (%s)\n", - i, stat_msg); - } - } - } - xtalk_dev->xproto.name = protoname; - xtalk_dev->xproto.proto_version = (xproto) ? xproto->proto_version : 0; - return 0; -} - -struct xtalk_command *new_command( - const struct xtalk_device *xtalk_dev, - uint8_t op, uint16_t extra_data) -{ - const struct xtalk_protocol *xproto; - struct xtalk_command *cmd; - const struct xtalk_command_desc *desc; - uint16_t len; - - xproto = &xtalk_dev->xproto; - desc = get_command_desc(xproto, op); - if (!desc) { - ERR("Unknown op=0x%X.\n", op); - return NULL; - } - DBG("OP=0x%X [%s] (extra_data %d)\n", op, desc->name, extra_data); - len = desc->len + extra_data; - cmd = malloc(len); - if (!cmd) { - ERR("Out of memory\n"); - return NULL; - } - if (extra_data) { - uint8_t *ptr = (uint8_t *)cmd; - - DBG("clear extra_data (%d bytes)\n", extra_data); - memset(ptr + desc->len, 0, extra_data); - } - cmd->header.op = op; - cmd->header.len = len; - cmd->header.seq = 0; /* Overwritten in send_usb() */ - return cmd; -} - -void xtalk_dump_command(struct xtalk_command *cmd) -{ - uint16_t len; - int i; - - len = cmd->header.len; - if (len < sizeof(struct xtalk_header)) { - ERR("Command too short (%d)\n", len); - return; - } - INFO("DUMP: OP=0x%X len=%d seq=%d\n", - cmd->header.op, cmd->header.len, cmd->header.seq); - for (i = 0; i < len - sizeof(struct xtalk_header); i++) - INFO(" %2d. 0x%X\n", i, cmd->alt.raw_data[i]); -} - -static int send_command(struct xtalk_device *xtalk_dev, - struct xtalk_command *cmd, int timeout) -{ - int ret; - int len; - void *priv = xtalk_dev->transport_priv; - - len = cmd->header.len; - cmd->header.seq = xtalk_dev->tx_sequenceno; - - ret = xtalk_dev->ops.send_func(priv, (char *)cmd, len, timeout); - if (ret < 0) - DBG("send_func failed ret=%d\n", ret); - xtalk_dev->tx_sequenceno++; - return ret; -} - -static struct xtalk_command *recv_command(struct xtalk_device *xtalk_dev, - int timeout) -{ - struct xtalk_command *reply; - void *priv = xtalk_dev->transport_priv; - size_t psize = xtalk_dev->packet_size; - int ret; - - reply = malloc(psize); - if (!reply) { - ERR("Out of memory\n"); - goto err; - } - reply->header.len = 0; - ret = xtalk_dev->ops.recv_func(priv, (char *)reply, psize, timeout); - if (ret < 0) { - ERR("Receive from usb failed.\n"); - goto err; - } else if (ret == 0) { - goto err; /* No reply */ - } - if (ret != reply->header.len) { - ERR("Wrong length received: got %d bytes, " - "but length field says %d bytes%s\n", - ret, reply->header.len, - (ret == 1) ? ". Old USB firmware?" : ""); - goto err; - } - /* dump_packet(LOG_DEBUG, DBG_MASK, __func__, (char *)reply, ret); */ - return reply; -err: - if (reply) { - memset(reply, 0, psize); - free_command(reply); - } - return NULL; -} - - -__attribute__((warn_unused_result)) -int process_command( - struct xtalk_device *xtalk_dev, - struct xtalk_command *cmd, - struct xtalk_command **reply_ref) -{ - const struct xtalk_protocol *xproto; - struct xtalk_command *reply = NULL; - const struct xtalk_command_desc *reply_desc; - const struct xtalk_command_desc *expected; - const struct xtalk_command_desc *cmd_desc; - uint8_t reply_op; - const char *protoname; - int ret; - - xproto = &xtalk_dev->xproto; - protoname = (xproto) ? xproto->name : "GLOBAL"; - /* So the caller knows if a reply was received */ - if (reply_ref) - *reply_ref = NULL; - reply_op = cmd->header.op | XTALK_REPLY_MASK; - cmd_desc = get_command_desc(xproto, cmd->header.op); - expected = get_command_desc(xproto, reply_op); - ret = send_command(xtalk_dev, cmd, TIMEOUT); - if (!reply_ref) { - DBG("No reply requested\n"); - goto out; - } - if (ret < 0) { - ERR("send_command failed: %d\n", ret); - goto out; - } - reply = recv_command(xtalk_dev, TIMEOUT); - if (!reply) { - ERR("recv_command failed\n"); - ret = -EPROTO; - goto out; - } - *reply_ref = reply; - if ((reply->header.op & 0x80) != 0x80) { - ERR("Unexpected reply op=0x%02X, should have MSB set.\n", - reply->header.op); - ret = -EPROTO; - goto out; - } - DBG("REPLY OP: 0x%X\n", reply->header.op); - reply_desc = get_command_desc(xproto, reply->header.op); - if (!reply_desc) { - ERR("Unknown reply (proto=%s) op=0x%02X\n", - protoname, reply->header.op); - ret = -EPROTO; - goto out; - } - DBG("REPLY NAME: %s\n", reply_desc->name); - if (reply->header.op == XTALK_ACK) { - int status = CMD_FIELD(reply, XTALK, ACK, stat); - - if (expected) { - ERR("Expected OP=0x%02X: Got ACK(%d): %s\n", - reply_op, - status, - ack_status_msg(xproto, status)); - ret = -EPROTO; - goto out; - } else if (status != STAT_OK) { - - ERR("Got ACK (for OP=0x%X [%s]): %d %s\n", - cmd->header.op, - cmd_desc->name, - status, ack_status_msg(xproto, status)); - ret = -EPROTO; - goto out; - } - /* Good expected ACK ... */ - } else if (reply->header.op != reply_op) { - ERR("Expected OP=0x%02X: Got OP=0x%02X\n", - reply_op, reply->header.op); - ret = -EPROTO; - goto out; - } - if (expected && expected->len > reply->header.len) { - ERR("Expected len=%d: Got len=%d\n", - expected->len, reply->header.len); - ret = -EPROTO; - goto out; - } - if (cmd->header.seq != reply->header.seq) { - ERR("Expected seq=%d: Got seq=%d\n", - cmd->header.seq, reply->header.seq); - ret = -EPROTO; - goto out; - } - ret = reply->header.len; /* All good, return the length */ - DBG("returning reply op 0x%X (%d bytes)\n", reply->header.op, ret); -out: - free_command(cmd); - if (!reply_ref && reply) - free_command(reply); - return ret; -} - -/* - * Protocol Commands - */ - -int xtalk_proto_query(struct xtalk_device *xtalk_dev) -{ - struct xtalk_command *cmd; - struct xtalk_command *reply; - uint8_t proto_version; - int ret; - - DBG("\n"); - assert(xtalk_dev != NULL); - proto_version = xtalk_dev->xproto.proto_version; - cmd = new_command(xtalk_dev, XTALK_PROTO_GET, 0); - if (!cmd) { - ERR("new_command failed\n"); - return -ENOMEM; - } - /* Protocol Version */ - CMD_FIELD(cmd, XTALK, PROTO_GET, proto_version) = proto_version; - ret = process_command(xtalk_dev, cmd, &reply); - if (ret < 0) { - ERR("process_command failed: %d\n", ret); - goto out; - } - xtalk_dev->xtalk_proto_version = - CMD_FIELD(reply, XTALK, PROTO_GET_REPLY, proto_version); - if (xtalk_dev->xtalk_proto_version != proto_version) { - DBG("Got %s protocol version: 0x%02x (expected 0x%02x)\n", - xtalk_dev->xproto.name, - xtalk_dev->xtalk_proto_version, - proto_version); - ret = xtalk_dev->xtalk_proto_version; - goto out; - } - DBG("Protocol version: %02x\n", xtalk_dev->xtalk_proto_version); - ret = xtalk_dev->xtalk_proto_version; -out: - free_command(reply); - return ret; -} - -/* - * Wrappers - */ - -struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, - size_t packet_size, void *priv) -{ - struct xtalk_device *xtalk_dev; - int ret; - - DBG("\n"); - assert(ops != NULL); - xtalk_dev = malloc(sizeof(*xtalk_dev)); - if (!xtalk_dev) { - ERR("Allocating XTALK device memory failed\n"); - return NULL; - } - memset(xtalk_dev, 0, sizeof(*xtalk_dev)); - memcpy((void *)&xtalk_dev->ops, (const void *)ops, - sizeof(xtalk_dev->ops)); - xtalk_dev->transport_priv = priv; - xtalk_dev->packet_size = packet_size; - xtalk_dev->tx_sequenceno = 1; - ret = xtalk_set_protocol(xtalk_dev, NULL); - if (ret < 0) { - ERR("GLOBAL Protocol registration failed: %d\n", ret); - goto err; - } - return xtalk_dev; - -err: - if (xtalk_dev) - xtalk_delete(xtalk_dev); - return NULL; -} - -void xtalk_delete(struct xtalk_device *xtalk_dev) -{ - void *priv; - - if (!xtalk_dev) - return; - DBG("\n"); - priv = xtalk_dev->transport_priv; - assert(priv); - xtalk_dev->tx_sequenceno = 0; - assert(&xtalk_dev->ops != NULL); - assert(&xtalk_dev->ops.close_func != NULL); - xtalk_dev->ops.close_func(priv); -} diff --git a/xpp/xtalk/xtalk.h b/xpp/xtalk/xtalk.h deleted file mode 100644 index 88f0260..0000000 --- a/xpp/xtalk/xtalk.h +++ /dev/null @@ -1,178 +0,0 @@ -#ifndef XTALK_H -#define XTALK_H -/* - * Written by Oron Peled - * Copyright (C) 2009, 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. - * - */ - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * XTALK - Base protocol for our USB devices - * It is meant to provide a common base for layered - * protocols (dialects) - */ - -#include -#include -/* Definitions common to the firmware (in include/ directory) */ -#include - -#ifdef __GNUC__ -#define PACKED __attribute__((packed)) -#else -#error "We do not know how your compiler packs structures" -#endif - -struct xtalk_device; -struct xtalk_command_desc; - -typedef int (*xtalk_cmd_callback_t)( - struct xtalk_device *xtalk_dev, - struct xtalk_command_desc *xtalk_cmd); - -/* Describe a single xtalk command */ -struct xtalk_command_desc { - uint8_t op; - const char *name; - xtalk_cmd_callback_t callback; - uint16_t len; /* Minimal length */ -}; - -/* Define a complete protocol */ -struct xtalk_protocol { - const char *name; - uint8_t proto_version; - struct xtalk_command_desc commands[MAX_OPS]; - const char *ack_statuses[MAX_STATUS]; -}; - -/* - * The common header of every xtalk command - * in every xtalk dialect. - */ -struct xtalk_header { - uint16_t len; - uint16_t seq; - uint8_t op; /* MSB: 0 - to device, 1 - from device */ -} PACKED; - -struct xtalk_command { - /* Common part */ - struct xtalk_header header; - /* Each dialect has its own data members */ - union private_data { - uint8_t raw_data[0]; - } PACKED alt; -} PACKED; - -/* - * Macros to unify access to protocol packets and fields: - * p - signify the dialect prefix (XTALK for base protocol) - * o - signify command op (e.g: ACK) - * cmd - A pointer to struct xtalk_command - * field - field name (e.g: raw_data) - */ -#define XTALK_STRUCT(p, o) p ## _struct_ ## o -#define XTALK_PDATA(o) xtalk_privdata_ ## o -#define XTALK_CMD_PTR(cmd, p) ((union XTALK_PDATA(p)*)&((cmd)->alt)) -#define CMD_FIELD(cmd, p, o, field) \ - (XTALK_CMD_PTR(cmd, p)->XTALK_STRUCT(p, o).field) -#define CMD_DEF(p, o, ...) struct XTALK_STRUCT(p, o) { \ - __VA_ARGS__ \ - } PACKED XTALK_STRUCT(p, o) -#define MEMBER(p, o) struct XTALK_STRUCT(p, o) XTALK_STRUCT(p, o) - -/* Wrappers for transport (xusb) functions */ -struct xtalk_ops { - int (*send_func)(void *transport_priv, void *data, size_t len, - int timeout); - int (*recv_func)(void *transport_priv, void *data, size_t maxlen, - int timeout); - int (*close_func)(void *transport_priv); -}; - -/* - * Base XTALK device. A pointer to this struct - * should be included in the struct representing - * the dialect. - */ -struct xtalk_device; - -/* high-level */ -struct xtalk_device *xtalk_new(const struct xtalk_ops *ops, - size_t packet_size, void *transport_priv); -void xtalk_delete(struct xtalk_device *dev); -int xtalk_set_protocol(struct xtalk_device *xtalk_dev, - const struct xtalk_protocol *xproto); -int xtalk_proto_query(struct xtalk_device *dev); -void xtalk_dump_command(struct xtalk_command *cmd); - -/* low-level */ -int process_command( - struct xtalk_device *dev, - struct xtalk_command *cmd, - struct xtalk_command **reply_ref); -struct xtalk_command *new_command( - const struct xtalk_device *xtalk_dev, - uint8_t op, uint16_t extra_data); -void free_command(struct xtalk_command *cmd); - -/* - * Convenience macros to define entries in a protocol command table: - * p - signify the dialect prefix (XTALK for base protocol) - * o - signify command op (e.g: ACK) - * cb - A callback function (type xtalk_cmd_callback_t) - */ -#define CMD_RECV(p, o, cb) \ - [p ## _ ## o | XTALK_REPLY_MASK] = { \ - .op = (p ## _ ## o) | XTALK_REPLY_MASK, \ - .name = (#o "_reply"), \ - .callback = (cb), \ - .len = \ - sizeof(struct xtalk_header) + \ - sizeof(struct XTALK_STRUCT(p, o)), \ - } - -#define CMD_SEND(p, o) \ - [p ## _ ## o] = { \ - .op = (p ## _ ## o), \ - .name = (#o), \ - .callback = NULL, \ - .len = \ - sizeof(struct xtalk_header) + \ - sizeof(struct XTALK_STRUCT(p, o)), \ - } - -/* - * Convenience macro to define statuses: - * x - status code (e.g: OK) - * m - status message (const char *) - */ -#define ACK_STAT(x, m) [STAT_ ## x] = (m) - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* XTALK_H */ diff --git a/xpp/xtalk/xtalk_base.c b/xpp/xtalk/xtalk_base.c index 4dbb5ec..ee9e462 100644 --- a/xpp/xtalk/xtalk_base.c +++ b/xpp/xtalk/xtalk_base.c @@ -351,3 +351,8 @@ void xtalk_base_delete(struct xtalk_base *xtalk_base) memset(xtalk_base, 0, sizeof(*xtalk_base)); free(xtalk_base); } + +struct xusb_iface *xusb_iface_of_xtalk_base(const struct xtalk_base *xtalk_base) +{ + return xtalk_base->transport_priv; +} diff --git a/xpp/xtalk/xtalk_defs.h b/xpp/xtalk/xtalk_defs.h deleted file mode 100644 index 826ad67..0000000 --- a/xpp/xtalk/xtalk_defs.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef XTALK_DEFS_H -#define XTALK_DEFS_H - -#define MAX_OPS 256 /* single byte */ -#define MAX_STATUS 256 /* single byte */ - -#define XTALK_REPLY_MASK 0x80 /* Every reply has this bit */ - -#define PRIVATE_OP_FIRST 0x05 -#define PRIVATE_OP_LAST 0x7F -#define IS_PRIVATE_OP(x) ( \ - (((x) & ~(XTALK_REPLY_MASK)) >= PRIVATE_OP_FIRST) && \ - (((x) & ~(XTALK_REPLY_MASK)) <= PRIVATE_OP_LAST) \ - ) - -#define XTALK_ACK 0x80 -#define XTALK_PROTO_GET 0x01 -#define XTALK_PROTO_GET_REPLY (XTALK_PROTO_GET | XTALK_REPLY_MASK) -#define XTALK_FWVERS_GET 0x11 -#define XTALK_FWVERS_GET_REPLY (XTALK_FWVERS_GET | XTALK_REPLY_MASK) -/* Get EEPROM table contents Product/Vendor Id ... */ -#define XTALK_CAPS_GET 0x0E -#define XTALK_CAPS_GET_REPLY (XTALK_CAPS_GET | XTALK_REPLY_MASK) - -/*------------- XTALK: statuses in ACK ---------------------------------------*/ -#define STAT_OK 0x00 /* OK */ -#define STAT_FAIL 0x01 /* last command failed */ -#define STAT_RESET_FAIL 0x02 /* reset failed */ -#define STAT_NODEST 0x03 /* No destination is selected */ -#define STAT_MISMATCH 0x04 /* Data mismatch */ -#define STAT_NOACCESS 0x05 /* No access */ -#define STAT_BAD_CMD 0x06 /* Bad command */ -#define STAT_TOO_SHORT 0x07 /* Packet is too short */ -#define STAT_ERROFFS 0x08 /* Offset error (not used) */ -#define STAT_NO_LEEPROM 0x0A /* Large EEPROM was not found */ -#define STAT_NO_EEPROM 0x0B /* No EEPROM was found */ -#define STAT_WRITE_FAIL 0x0C /* Writing to device failed */ -#define STAT_NOPWR_ERR 0x10 /* No power on USB connector */ - - -#endif /* XTALK_DEFS_H */ diff --git a/xpp/xtalk/xusb.c b/xpp/xtalk/xusb.c deleted file mode 100644 index d33f013..0000000 --- a/xpp/xtalk/xusb.c +++ /dev/null @@ -1,943 +0,0 @@ -/* - * Written by Oron Peled - * Copyright (C) 2008, 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. - * - */ - -#define _GNU_SOURCE /* for memrchr() */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DBG_MASK 0x01 -#define TIMEOUT 500 -#define MAX_RETRIES 10 - -struct xusb { - struct usb_device *dev; - usb_dev_handle *handle; - const struct xusb_spec *spec; - char iManufacturer[BUFSIZ]; - char iProduct[BUFSIZ]; - char iSerialNumber[BUFSIZ]; - char iInterface[BUFSIZ]; - char devpath_tail[PATH_MAX + 1]; - int bus_num; - int device_num; - int interface_num; - int ep_out; - int ep_in; - int is_usb2; - int is_claimed; - int is_open; - size_t packet_size; -}; - -static void xusb_init(); - -/* - * XTALK_OPTIONS: - * A white-space separated list of options, read from the environment - * variable of that name. Existing options: - * - * - "use-clear-halt" -- force USB "clear_halt" operation during - * device initialization (this is the default) - * - "no-use-clear-halt" -- force no USB "clear_halt" operation during - * device initialization - * - "no-lock" -- prevent using global sempahore to serialize libusb - * initialization. Previously done via "XUSB_NOLOCK" - * environment variable. - */ -int xtalk_parse_options(void); -int xtalk_option_use_clear_halt(void); -int xtalk_option_no_lock(void); - -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) -{ - DBG("Initialize %s: interfaces=%d using interface num=%d endpoints=%d " - "(OUT=0x%02X, IN=0x%02X)\n", - name, nifaces, iface, nep, ep_out, ep_in); - memset(spec, 0, sizeof(*spec)); - spec->name = name; - spec->num_interfaces = nifaces; - spec->my_interface_num = iface; - spec->num_endpoints = nep; - spec->my_vendor_id = vendor_id; - spec->my_product_id = product_id; - spec->my_ep_in = ep_in; - spec->my_ep_out = ep_out; -} - -#define EP_OUT(xusb) ((xusb)->spec->my_ep_out) -#define EP_IN(xusb) ((xusb)->spec->my_ep_in) - -/* - * USB handling - */ - -static int get_usb_string(struct xusb *xusb, uint8_t item, char *buf) -{ - char tmp[BUFSIZ]; - int ret; - - assert(xusb->handle); - if (!item) - return 0; - ret = usb_get_string_simple(xusb->handle, item, tmp, BUFSIZ); - if (ret <= 0) - return ret; - return snprintf(buf, BUFSIZ, "%s", tmp); -} - -static const struct usb_interface_descriptor *get_interface( - const struct usb_device *dev, - int my_interface_num, - int num_interfaces) -{ - const struct usb_interface *interface; - const struct usb_interface_descriptor *iface_desc; - const struct usb_config_descriptor *config_desc; - int num_altsetting; - - config_desc = dev->config; - if (!config_desc) { - ERR("No configuration descriptor: strange USB1 controller?\n"); - return NULL; - } - if (num_interfaces && config_desc->bNumInterfaces != num_interfaces) { - DBG("Wrong number of interfaces: have %d need %d\n", - config_desc->bNumInterfaces, num_interfaces); - return NULL; - } - interface = &config_desc->interface[my_interface_num]; - assert(interface != NULL); - iface_desc = interface->altsetting; - num_altsetting = interface->num_altsetting; - assert(num_altsetting != 0); - assert(iface_desc != NULL); - return iface_desc; -} - -static int match_interface(const struct usb_device *dev, - const struct xusb_spec *spec) -{ - const struct usb_device_descriptor *dev_desc; - const struct usb_interface_descriptor *iface_desc; - - dev_desc = &dev->descriptor; - assert(dev_desc); - DBG("Checking: %04X:%04X interfaces=%d interface num=%d endpoints=%d: " - "\"%s\"\n", - spec->my_vendor_id, - spec->my_product_id, - spec->num_interfaces, - spec->my_interface_num, - spec->num_endpoints, - spec->name); - if (dev_desc->idVendor != spec->my_vendor_id) { - DBG("Wrong vendor id 0x%X\n", dev_desc->idVendor); - return 0; - } - if (dev_desc->idProduct != spec->my_product_id) { - DBG("Wrong product id 0x%X\n", dev_desc->idProduct); - return 0; - } - iface_desc = get_interface(dev, spec->my_interface_num, - spec->num_interfaces); - if (!iface_desc) { - ERR("Could not get interface descriptor of device: %s\n", - usb_strerror()); - return 0; - } - if (iface_desc->bInterfaceClass != 0xFF) { - DBG("Wrong interface class 0x%X\n", - iface_desc->bInterfaceClass); - return 0; - } - if (iface_desc->bInterfaceNumber != spec->my_interface_num) { - DBG("Wrong interface number %d (expected %d)\n", - iface_desc->bInterfaceNumber, spec->my_interface_num); - return 0; - } - if (iface_desc->bNumEndpoints != spec->num_endpoints) { - DBG("Wrong number of endpoints %d\n", - iface_desc->bNumEndpoints); - return 0; - } - return 1; -} - -#define GET_USB_STRING(xusb, from, item) \ - get_usb_string((xusb), (from)->item, xusb->item) - -static int xusb_fill_strings(struct xusb *xusb) -{ - const struct usb_device_descriptor *dev_desc; - const struct usb_interface_descriptor *iface_desc; - - - dev_desc = &xusb->dev->descriptor; - assert(dev_desc); - if (GET_USB_STRING(xusb, dev_desc, iManufacturer) < 0) { - ERR("Failed reading iManufacturer string: %s\n", - usb_strerror()); - return 0; - } - if (GET_USB_STRING(xusb, dev_desc, iProduct) < 0) { - ERR("Failed reading iProduct string: %s\n", - usb_strerror()); - return 0; - } - if (GET_USB_STRING(xusb, dev_desc, iSerialNumber) < 0) { - ERR("Failed reading iSerialNumber string: %s\n", - usb_strerror()); - return 0; - } - iface_desc = get_interface(xusb->dev, xusb->interface_num, 0); - if (!iface_desc) { - ERR("Could not get interface descriptor of device: %s\n", - usb_strerror()); - return 0; - } - if (GET_USB_STRING(xusb, iface_desc, iInterface) < 0) { - ERR("Failed reading iInterface string: %s\n", usb_strerror()); - return 0; - } - return 1; -} - -static int xusb_open(struct xusb *xusb) -{ - assert(xusb); - if (xusb->is_open) - return 1; - xusb->handle = usb_open(xusb->dev); - if (!xusb->handle) { - ERR("Failed to open usb device '%s': %s\n", - xusb->devpath_tail, usb_strerror()); - return 0; - } - xusb->is_open = 1; - return 1; -} - -int xusb_claim_interface(struct xusb *xusb) -{ - const struct usb_device_descriptor *dev_desc; - int ret; - - assert(xusb); - xusb_open(xusb); /* If it's not open yet... */ - if (usb_claim_interface(xusb->handle, xusb->interface_num) != 0) { - ERR("usb_claim_interface %d in '%s': %s\n", - xusb->interface_num, - xusb->devpath_tail, - usb_strerror()); - return 0; - } - xusb->is_claimed = 1; - xusb_fill_strings(xusb); - dev_desc = &xusb->dev->descriptor; - DBG("ID=%04X:%04X Manufacturer=[%s] Product=[%s] " - "SerialNumber=[%s] Interface=[%s]\n", - dev_desc->idVendor, - dev_desc->idProduct, - xusb->iManufacturer, - xusb->iProduct, - xusb->iSerialNumber, - xusb->iInterface); - if (xtalk_option_use_clear_halt()) { - DBG("Using clear_halt()\n"); - if (usb_clear_halt(xusb->handle, EP_OUT(xusb)) != 0) { - ERR("Clearing output endpoint: %s\n", usb_strerror()); - return 0; - } - if (usb_clear_halt(xusb->handle, EP_IN(xusb)) != 0) { - ERR("Clearing input endpoint: %s\n", usb_strerror()); - return 0; - } - } - ret = xusb_flushread(xusb); - if (ret < 0) { - ERR("xusb_flushread failed: %d\n", ret); - return 0; - } - return 1; -} - -static void xusb_list_dump(struct xlist_node *xusb_list) -{ - struct xlist_node *curr; - struct xusb *xusb; - - for (curr = xusb_list->next; curr != xusb_list; curr = curr->next) { - struct usb_device *dev; - struct usb_bus *bus; - struct usb_device_descriptor *dev_desc; - - xusb = curr->data; - assert(xusb); - dev = xusb->dev; - assert(dev); - bus = dev->bus; - assert(bus); - dev_desc = &dev->descriptor; - assert(dev_desc); - DBG("usb:ID=%04X:%04X [%s / %s / %s], (%s/%s)\n", - dev_desc->idVendor, - dev_desc->idProduct, - xusb->iManufacturer, - xusb->iProduct, - xusb->iSerialNumber, - bus->dirname, - dev->filename - ); - } -} - -void xusb_destroy(struct xusb *xusb) -{ - if (xusb) { - xusb_close(xusb); - memset(xusb, 0, sizeof(*xusb)); - free(xusb); - } -} - -static struct xusb *xusb_new(struct usb_device *dev, - const struct xusb_spec *spec) -{ - struct usb_device_descriptor *dev_desc; - struct usb_config_descriptor *config_desc; - struct usb_interface *interface; - struct usb_interface_descriptor *iface_desc; - struct usb_endpoint_descriptor *endpoint; - size_t max_packet_size; - int i; - struct xusb *xusb = NULL; - - /* - * Get information from the usb_device - */ - dev_desc = &dev->descriptor; - if (!dev_desc) { - ERR("usb device without a device descriptor\n"); - goto fail; - } - config_desc = dev->config; - if (!config_desc) { - ERR("usb device without a configuration descriptor\n"); - goto fail; - } - interface = &config_desc->interface[spec->my_interface_num]; - iface_desc = interface->altsetting; - endpoint = iface_desc->endpoint; - /* Calculate max packet size */ - max_packet_size = PACKET_SIZE; - for (i = 0; i < iface_desc->bNumEndpoints; i++, endpoint++) { - DBG("Validating endpoint @ %d (interface %d)\n", - i, spec->my_interface_num); - if (endpoint->bEndpointAddress == spec->my_ep_out || - endpoint->bEndpointAddress == spec->my_ep_in) { - if (endpoint->wMaxPacketSize > PACKET_SIZE) { - ERR("EP #%d wMaxPacketSize too large (%d)\n", - i, endpoint->wMaxPacketSize); - goto fail; - } - if (endpoint->wMaxPacketSize < max_packet_size) - max_packet_size = endpoint->wMaxPacketSize; - } - } - /* Fill xusb */ - xusb = malloc(sizeof(*xusb)); - if (!xusb) { - ERR("Out of memory"); - goto fail; - } - memset(xusb, 0, sizeof(*xusb)); - xusb->dev = dev; - xusb->spec = spec; - sscanf(dev->bus->dirname, "%d", &xusb->bus_num); - sscanf(dev->filename, "%d", &xusb->device_num); - snprintf(xusb->devpath_tail, PATH_MAX, "%03d/%03d", - xusb->bus_num, xusb->device_num); - xusb->interface_num = spec->my_interface_num; - xusb->ep_out = spec->my_ep_out; - xusb->ep_in = spec->my_ep_in; - xusb->packet_size = max_packet_size; - xusb->is_usb2 = (max_packet_size == 512); - if (!xusb_open(xusb)) { - ERR("Failed opening device: %04X:%04X - %s\n", - dev_desc->idVendor, - dev_desc->idProduct, - xusb->devpath_tail); - goto fail; - } - DBG("%04X:%04X - %s\n", - dev_desc->idVendor, - dev_desc->idProduct, - xusb->devpath_tail); - return xusb; -fail: - xusb_destroy(xusb); - return NULL; -} - -struct xusb *xusb_find_iface(const char *devpath, - int iface_num, - int ep_out, - int ep_in, - struct xusb_spec *dummy_spec) -{ - struct usb_bus *bus; - - DBG("\n"); - xusb_init(); - for (bus = usb_get_busses(); bus; bus = bus->next) { - int bus_num; - char tmppath[PATH_MAX + 1]; - struct usb_device *dev; - - tmppath[0] = '\0'; - sscanf(bus->dirname, "%d", &bus_num); - snprintf(tmppath, sizeof(tmppath), "%03d", bus_num); - DBG("Check bus %d: %s ? %s\n", bus_num, tmppath, devpath); - if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) - continue; - DBG("Matched bus %d\n", bus_num); - for (dev = bus->devices; dev; dev = dev->next) { - struct usb_device_descriptor *dev_desc; - struct usb_config_descriptor *config_desc; - struct usb_interface *interface; - struct xusb *xusb; - int device_num; - - sscanf(dev->filename, "%d", &device_num); - DBG("Check device %d\n", device_num); - snprintf(tmppath, sizeof(tmppath), "%03d/%03d", - bus_num, device_num); - if (strncmp(tmppath, devpath, strlen(tmppath)) != 0) - continue; - dev_desc = &dev->descriptor; - assert(dev_desc); - config_desc = dev->config; - assert(config_desc); - interface = config_desc->interface; - assert(interface); - DBG("Matched device %s: %X:%X\n", tmppath, - dev_desc->idVendor, dev_desc->idProduct); - assert(dummy_spec); - xusb_init_spec(dummy_spec, "", - dev_desc->idVendor, dev_desc->idProduct, - config_desc->bNumInterfaces, - iface_num, - interface->altsetting->bNumEndpoints, - ep_out, ep_in); - xusb = xusb_new(dev, dummy_spec); - if (!xusb) - ERR("xusb allocation failed\n"); - return xusb; - } - } - return NULL; -} - -static const char *path_tail(const char *path) -{ - const char *p; - - assert(path != NULL); - /* Find last '/' */ - p = memrchr(path, '/', strlen(path)); - if (!p) { - ERR("Missing a '/' in %s\n", path); - return NULL; - } - /* Search for a '/' before that */ - p = memrchr(path, '/', p - path); - if (!p) - p = path; /* No more '/' */ - else - p++; /* skip '/' */ - return p; -} - -int xusb_filter_bypath(const struct xusb *xusb, void *data) -{ - const char *p; - const char *path = data; - - DBG("%s\n", path); - assert(path != NULL); - p = path_tail(path); - if (strcmp(xusb->devpath_tail, p) != 0) { - DBG("device path missmatch: '%s' != '%s'\n", - xusb->devpath_tail, p); - return 0; - } - return 1; -} - -struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, - const char *path) -{ - struct xlist_node *xlist; - struct xlist_node *head; - struct xusb *xusb; - - xlist = xusb_find_byproduct(specs, numspecs, - xusb_filter_bypath, (void *)path); - head = xlist_shift(xlist); - if (!head) - return NULL; - if (!xlist_empty(xlist)) { - ERR("Too many matches (extra %zd) to '%s'\n", - xlist_length(xlist), path); - return NULL; - } - xusb = head->data; - xlist_destroy(xlist, NULL); - return xusb; -} - -struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, - int numspecs, xusb_filter_t filterfunc, void *data) -{ - struct xlist_node *xlist; - struct usb_bus *bus; - struct usb_device *dev; - - DBG("specs(%d)\n", numspecs); - xlist = xlist_new(NULL); - if (!xlist) { - ERR("Failed allocation new xlist"); - goto fail_xlist; - } - 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; - struct xlist_node *item; - int i; - - dev_desc = &dev->descriptor; - assert(dev_desc); - DBG("usb:%s/%s: ID=%04X:%04X\n", - dev->bus->dirname, - dev->filename, - dev_desc->idVendor, - dev_desc->idProduct); - for (i = 0; i < numspecs; i++) { - struct xusb *xusb; - const struct xusb_spec *sp = &specs[i]; - - if (!match_interface(dev, sp)) - continue; - xusb = xusb_new(dev, sp); - if (!xusb) { - ERR("xusb allocation failed\n"); - goto fail_malloc; - } - if (filterfunc && !filterfunc(xusb, data)) { - xusb_destroy(xusb); - continue; - } - item = xlist_new(xusb); - xlist_append_item(xlist, item); - break; - } - } - } - xusb_list_dump(xlist); - return xlist; -fail_malloc: - xlist_destroy(xlist, NULL); -fail_xlist: - return NULL; -} - -struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, - xusb_filter_t filterfunc, void *data) -{ - struct xlist_node *xusb_list; - struct xlist_node *curr; - int num; - struct xusb *xusb = NULL; - - xusb_list = xusb_find_byproduct(specs, numspecs, filterfunc, data); - num = xlist_length(xusb_list); - DBG("total %d devices\n", num); - switch (num) { - case 0: - ERR("No matching device.\n"); - break; - case 1: - curr = xlist_shift(xusb_list); - xusb = curr->data; - xlist_destroy(curr, NULL); - xlist_destroy(xusb_list, NULL); - if (!xusb_claim_interface(xusb)) { - xusb_destroy(xusb); - return NULL; - } - xusb_showinfo(xusb); - break; - default: - ERR("Too many devices (%d). Aborting.\n", num); - break; - } - return xusb; -} - -int xusb_interface(struct xusb *xusb) -{ - return xusb->interface_num; -} - -size_t xusb_packet_size(const struct xusb *xusb) -{ - return xusb->packet_size; -} - -/* - * MP device handling - */ -void xusb_showinfo(const struct xusb *xusb) -{ - struct usb_device_descriptor *dev_desc; - struct usb_device *dev; - - assert(xusb != NULL); - dev = xusb->dev; - dev_desc = &dev->descriptor; - if (verbose <= LOG_INFO) { - INFO("usb:%s/%s: ID=%04X:%04X [%s / %s / %s]\n", - dev->bus->dirname, - dev->filename, - dev_desc->idVendor, - dev_desc->idProduct, - xusb->iManufacturer, - xusb->iProduct, - xusb->iSerialNumber); - } else { - printf("USB Bus/Device: [%s/%s] (%s,%s)\n", - dev->bus->dirname, - dev->filename, - (xusb->is_open) ? "open" : "closed", - (xusb->is_claimed) ? "claimed" : "unused"); - printf("USB Spec name: [%s]\n", xusb->spec->name); - printf("USB iManufacturer: [%s]\n", xusb->iManufacturer); - printf("USB iProduct: [%s]\n", xusb->iProduct); - printf("USB iSerialNumber: [%s]\n", xusb->iSerialNumber); - } -} - -const char *xusb_serial(const struct xusb *xusb) -{ - return xusb->iSerialNumber; -} - -const char *xusb_devpath(const struct xusb *xusb) -{ - return xusb->devpath_tail; -} - -const char *xusb_manufacturer(const struct xusb *xusb) -{ - return xusb->iManufacturer; -} - -const char *xusb_product(const struct xusb *xusb) -{ - return xusb->iProduct; -} - -uint16_t xusb_vendor_id(const struct xusb *xusb) -{ - return xusb->dev->descriptor.idVendor; -} - -uint16_t xusb_product_id(const struct xusb *xusb) -{ - return xusb->dev->descriptor.idProduct; -} - -const struct xusb_spec *xusb_spec(const struct xusb *xusb) -{ - return xusb->spec; -} - -int xusb_close(struct xusb *xusb) -{ - if (xusb) { - if (xusb->handle) { - assert(xusb->spec); - assert(xusb->spec->name); - DBG("Closing interface \"%s\"\n", xusb->spec->name); - if (xusb->is_claimed) { - if (usb_release_interface(xusb->handle, - xusb->spec->my_interface_num) != 0) - ERR("Releasing interface: usb: %s\n", - usb_strerror()); - xusb->is_claimed = 0; - } - if (xusb->is_open) { - if (usb_close(xusb->handle) != 0) { - ERR("Closing device: usb: %s\n", - usb_strerror()); - } - xusb->is_open = 0; - } - xusb->handle = NULL; - } - xusb = NULL; - } - return 0; -} - -int xusb_send(struct xusb *xusb, char *buf, int len, int timeout) -{ - int ret; - int retries = 0; - - dump_packet(LOG_DEBUG, DBG_MASK, __func__, buf, len); - if (EP_OUT(xusb) & USB_ENDPOINT_IN) { - ERR("%s called with an input endpoint 0x%x\n", - __func__, EP_OUT(xusb)); - return -EINVAL; - } -retry_write: - ret = usb_bulk_write(xusb->handle, EP_OUT(xusb), buf, len, timeout); - if (ret < 0) { - /* - * If the device was gone, it may be the - * result of renumeration. Ignore it. - */ - 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, "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; - } - if (!ret) { - 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, "xusb_send[ERR]", buf, len); - return -EFAULT; - } - return ret; -} - -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", - __func__, 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", - EP_IN(xusb), ret, usb_strerror()); - memset(buf, 0, len); - return ret; - } - if (!ret) { - 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, __func__, buf, ret); - return ret; -} - -int xusb_flushread(struct xusb *xusb) -{ - char tmpbuf[BUFSIZ]; - int ret; - - DBG("starting...\n"); - memset(tmpbuf, 0, BUFSIZ); - ret = xusb_recv(xusb, tmpbuf, BUFSIZ, 1); - if (ret < 0 && ret != -ETIMEDOUT) { - ERR("ret=%d\n", ret); - return ret; - } else if (ret > 0) { - DBG("Got %d bytes:\n", ret); - dump_packet(LOG_DEBUG, DBG_MASK, __func__, tmpbuf, ret); - } - 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; - -static void xusb_init() -{ - if (!initizalized) { - xtalk_parse_options(); - if (!xtalk_option_no_lock()) - xusb_lock_usb(); - usb_init(); - usb_find_busses(); - usb_find_devices(); - initizalized = 1; - if (!xtalk_option_no_lock()) - xusb_unlock_usb(); - } -} - -/* XTALK option handling */ -static int use_clear_halt = 1; -static int libusb_no_lock = 0; - -static int xtalk_one_option(const char *option_string) -{ - if (strcmp(option_string, "use-clear-halt") == 0) { - use_clear_halt = 1; - return 0; - } - if (strcmp(option_string, "no-use-clear-halt") == 0) { - use_clear_halt = 0; - return 0; - } - if (strcmp(option_string, "no-lock") == 0) { - libusb_no_lock = 1; - return 0; - } - ERR("Unknown XTALK_OPTIONS content: '%s'\n", option_string); - return -EINVAL; -} - -int xtalk_option_use_clear_halt(void) -{ - return use_clear_halt; -} - -int xtalk_option_no_lock(void) -{ - return libusb_no_lock; -} - -int xtalk_parse_options(void) -{ - char *xtalk_options; - char *saveptr; - char *token; - int ret; - - xtalk_options = getenv("XTALK_OPTIONS"); - if (!xtalk_options) - return 0; - token = strtok_r(xtalk_options, " \t", &saveptr); - while (token) { - ret = xtalk_one_option(token); - if (ret < 0) - return ret; - token = strtok_r(NULL, " \t", &saveptr); - } - return 0; -} - diff --git a/xpp/xtalk/xusb.h b/xpp/xtalk/xusb.h deleted file mode 100644 index 01e1861..0000000 --- a/xpp/xtalk/xusb.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef XUSB_H -#define XUSB_H -/* - * Written by Oron Peled - * Copyright (C) 2008, 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 -#include -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -/* - * Xorcom usb handling - */ - -#define PACKET_SIZE 512 - -/* - * Specify the wanted interface - */ -struct xusb_spec { - /* Sanity checks so we know it is our device indeed */ - int num_interfaces; - int num_endpoints; - char *name; /* For debug/output purpose */ - /* What we will actually use */ - uint16_t my_vendor_id; - uint16_t my_product_id; - int my_interface_num; - int my_ep_out; - int my_ep_in; -}; - -void xusb_init_spec(struct xusb_spec *xusb_spec, char *name, - uint16_t vendor_id, uint16_t product_id, - int nifaces, int iface, int nep, int ep_out, int ep_in); - -struct xusb; - -/* - * Prototypes - */ -typedef int (*xusb_filter_t)(const struct xusb *xusb, void *data); -struct xlist_node *xusb_find_byproduct(const struct xusb_spec *specs, - int numspecs, xusb_filter_t filterfunc, void *data); -struct xusb *xusb_find_bypath(const struct xusb_spec *specs, int numspecs, - const char *path); -struct xusb *xusb_open_one(const struct xusb_spec *specs, int numspecs, - xusb_filter_t filterfunc, void *data); -struct xusb *xusb_find_iface(const char *devpath, int iface_num, - int ep_out, int ep_in, struct xusb_spec *dummy); - -/* - * A convenience filter - */ -int xusb_filter_bypath(const struct xusb *xusb, void *data); - -int xusb_interface(struct xusb *xusb); -int xusb_claim_interface(struct xusb *xusb); -void xusb_destroy(struct xusb *xusb); -int xusb_close(struct xusb *xusb); -size_t xusb_packet_size(const struct xusb *xusb); -void xusb_showinfo(const struct xusb *xusb); -const char *xusb_serial(const struct xusb *xusb); -const char *xusb_manufacturer(const struct xusb *xusb); -const char *xusb_product(const struct xusb *xusb); -uint16_t xusb_vendor_id(const struct xusb *xusb); -uint16_t xusb_product_id(const struct xusb *xusb); -const char *xusb_devpath(const struct xusb *xusb); -const struct xusb_spec *xusb_spec(const struct xusb *xusb); -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 xusb_flushread(struct xusb *xusb); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* XUSB_H */ diff --git a/xpp/xtalk/xusb_libusbx.c b/xpp/xtalk/xusb_libusbx.c index 69670df..a23d4af 100644 --- a/xpp/xtalk/xusb_libusbx.c +++ b/xpp/xtalk/xusb_libusbx.c @@ -566,7 +566,7 @@ struct xusb_device *xusb_find_bypath(const char *path) ERR("usb device without a device descriptor\n"); continue; } - INFO("Found: %04x:%04x %s\n", + DBG("Found: %04x:%04x %s\n", dev_desc.idVendor, dev_desc.idProduct, devpath_tail); xusb_init_spec(spec, "", dev_desc.idVendor, dev_desc.idProduct);