[Pkg-voip-commits] [dahdi-tools] 258/285: xpp: migrate everything to libxtalk

tzafrir at debian.org tzafrir at debian.org
Thu Jul 7 19:19:08 UTC 2016


This is an automated email from the git hooks/post-receive script.

tzafrir pushed a commit to branch master
in repository dahdi-tools.

commit 0e6b068e8902eb6a96017e37b71bbe1a934a105a
Author: Oron Peled <oron.peled at xorcom.com>
Date:   Sun Dec 21 14:58:03 2014 -0500

    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 <oron.peled at xorcom.com>
    Signed-off-by: Tzafrir Cohen <tzafrir.cohen at xorcom.com>
---
 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            | 188 +++++++---
 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, 1004 insertions(+), 3014 deletions(-)

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 <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <xtalk/debug.h>
+#include <xtalk/xusb.h>
+#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 <mpptalk.h>
+
+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 <sys/types.h>
 #include <arpa/inet.h>
 #include <ctype.h>
-#include "mpp.h"
+#include <xtalk/debug.h>
 #include "mpptalk.h"
-#include <debug.h>
+#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 <errno.h>
 #include <assert.h>
 #include <arpa/inet.h>
-#include <debug.h>
+#include <autoconfig.h>
+#include <xtalk/debug.h>
+#include <xtalk/xusb.h>
 #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 <stdio.h>
 #include <ctype.h>
 #include <string.h>
-#include <debug.h>
+#include <xtalk/debug.h>
 #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 <getopt.h>
 #include <sys/types.h>
 #include <arpa/inet.h>
-#include "astribank_usb.h"
+#include <xtalk/debug.h>
+#include <xtalk/xusb.h>
 #include "mpptalk.h"
-#include <debug.h>
-#include <xusb.h>
+#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 <oron at actcom.co.il>
- * 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 <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <arpa/inet.h>
-#include <xusb.h>
-#include "astribank_usb.h"
-#include <debug.h>
-
-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 <oron at actcom.co.il>
- * 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 <stdio.h>
-#include <xusb.h>
-#include <xtalk.h>
-#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 <limits.h>
 #include <regex.h>
 #include <sys/time.h>
-#include "echo_loader.h"
-#include "debug.h"
+#include <unistd.h>
 #include <oct6100api/oct6100_api.h>
+#include <xtalk/debug.h>
+#include <xtalk/xusb.h>
+#include <astribank.h>
+#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 <stdint.h>
-#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 <oron at actcom.co.il>
- * 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 <mpptalk_defs.h>
-#include <stdint.h>
-#include <xtalk.h>
-
-#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 <assert.h>
 #include <errno.h>
 #include <arpa/inet.h>
+#include <xtalk/debug.h>
+#include <xtalk/proto.h>
 #include "hexfile.h"
-#include "astribank_usb.h"
-#include "mpp.h"
 #include "mpptalk.h"
-#include <debug.h>
-#include <xusb.h>
-#include <xtalk.h>
 
-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 <oron at actcom.co.il>
  * Copyright (C) 2008, Xorcom
@@ -22,64 +22,152 @@
  *
  */
 
-#include <stdint.h>
-#include <stdio.h>
-
-#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);
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * MPPTALK - Example XTALK dialect
+ */
+
+#include <xtalk/proto.h>
+#include <xtalk/proto_sync.h>
+
+#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 astribank_device *astribank, 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 astribank_device *astribank, 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 commands to FPGA
+ * serial sub-protocol to FPGA
  */
-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);
+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 <oron at actcom.co.il>
- * 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 <xtalk_defs.h>
-/*
- * 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 <stdlib.h>
 #include <errno.h>
 #include <regex.h>
+#include <xtalk/debug.h>
+#include <xtalk/xusb.h>
 #include "hexfile.h"
 #include "pic_loader.h"
-#include <debug.h>
-#include <xusb.h>
 
-#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 <stdint.h>
-#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 <oron at actcom.co.il>
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <arpa/inet.h>
-#include <xtalk.h>
-#include <debug.h>
-
-#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 <oron at actcom.co.il>
- * 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 <stdint.h>
-#include <stdlib.h>
-/* Definitions common to the firmware (in include/ directory) */
-#include <xtalk_defs.h>
-
-#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 <oron at actcom.co.il>
- * 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 <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <arpa/inet.h>
-#include <debug.h>
-#include <xusb.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
-
-#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, "<none>",
-				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 <oron at actcom.co.il>
- * 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 <stdio.h>
-#include <stdint.h>
-#include <usb.h>
-#include <xlist.h>
-
-#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, "<BYPATH>",
 			dev_desc.idVendor, dev_desc.idProduct);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/dahdi-tools.git



More information about the Pkg-voip-commits mailing list