From ce72dbea7d7405ed37456c89c8b0516188f57fc7 Mon Sep 17 00:00:00 2001 From: Peter Stuge Date: Fri, 16 Nov 2012 00:13:56 +0100 Subject: [PATCH 1/3] Find libusb-1.0 with pkg-config except on mingw, and fix #include path --- configure.ac | 22 +++++++++++++++------- libztex.h | 2 +- miner.h | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 179bec44..19cbfcde 100644 --- a/configure.ac +++ b/configure.ac @@ -343,16 +343,24 @@ if test "x$bitforce$modminer" != xnono; then fi AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno]) +PKG_PROG_PKG_CONFIG() + if test "x$ztex" != xno; then - AC_CHECK_LIB(usb-1.0, libusb_init, , - AC_MSG_ERROR([Could not find usb library - please install libusb])) - AC_DEFINE([HAVE_LIBUSB], [1], [Defined to 1 if libusb is wanted]) - USB_LIBS="-lusb-1.0" - USB_FLAGS="" + case $target in + *-*-mingw*) + # workaround for libusbx windows binaries not including a .pc file + LIBUSB_LIBS="-LC:/MinGW/lib -lusb-1.0" + LIBUSB_CFLAGS="-IC:/MinGW/include/libusb-1.0" + AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb-1.0]) + ;; + *) + PKG_CHECK_MODULES(LIBUSB, libusb-1.0, [AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb-1.0])], [AC_MSG_ERROR([Could not find usb library - please install libusb-1.0])]) + ;; + esac + USB_LIBS="$LIBUSB_LIBS" + USB_FLAGS="$LIBUSB_CFLAGS" fi -PKG_PROG_PKG_CONFIG() - PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.18.2], ,[AC_MSG_ERROR([Missing required libcurl dev >= 7.18.2])]) AC_SUBST(LIBCURL_LIBS) diff --git a/libztex.h b/libztex.h index d424545c..4b5dab3b 100644 --- a/libztex.h +++ b/libztex.h @@ -22,7 +22,7 @@ #ifndef __LIBZTEX_H__ #define __LIBZTEX_H__ -#include +#include #define LIBZTEX_MAX_DESCRIPTORS 512 #define LIBZTEX_SNSTRING_LEN 10 diff --git a/miner.h b/miner.h index 7d261c5f..f098e235 100644 --- a/miner.h +++ b/miner.h @@ -103,7 +103,7 @@ static inline int fsync (int fd) #endif #ifdef HAVE_LIBUSB - #include + #include #endif #ifdef USE_ZTEX From 4e706162c76a824f92d354918adf8fa64d436510 Mon Sep 17 00:00:00 2001 From: Peter Stuge Date: Fri, 16 Nov 2012 00:59:21 +0100 Subject: [PATCH 2/3] configure.ac: FreeBSD can't use pkg-config to find libusb-1.0 --- configure.ac | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configure.ac b/configure.ac index 19cbfcde..4fd93b28 100644 --- a/configure.ac +++ b/configure.ac @@ -353,6 +353,11 @@ if test "x$ztex" != xno; then LIBUSB_CFLAGS="-IC:/MinGW/include/libusb-1.0" AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb-1.0]) ;; + *-*-freebsd*) + LIBUSB_LIBS="-lusb" + LIBUSB_CFLAGS="" + AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb-1.0]) + ;; *) PKG_CHECK_MODULES(LIBUSB, libusb-1.0, [AC_DEFINE(HAVE_LIBUSB, 1, [Define if you have libusb-1.0])], [AC_MSG_ERROR([Could not find usb library - please install libusb-1.0])]) ;; From 972ddf74c7e12b5c0ba36363dc22b935e3922267 Mon Sep 17 00:00:00 2001 From: Peter Stuge Date: Fri, 23 Nov 2012 03:42:47 +0100 Subject: [PATCH 3/3] libztex: Work around ZTEX USB firmware bug exposed by the FreeBSD libusb The ZTEX USB firmware doesn't correctly support GET_DESCRIPTOR requests for string descriptors, specifically the device always returns the full string descriptor, even if the request wLength is shorter. The FreeBSD implementation of libusb_get_string_descriptor_ascii() first requests 4 (four) bytes to validate the start of the string descriptor, and since the device sends back too many bytes the USB host controller signals an error to FreeBSD which returns the error to us. In order to avoid this mess the libusb_get_string_descriptor_ascii() call is replaced with the way libusb-1.0 works; which makes only a single request to read the entire string descriptor. --- libztex.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libztex.c b/libztex.c index 78c8f51b..78ab9393 100644 --- a/libztex.c +++ b/libztex.c @@ -409,6 +409,7 @@ int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** zt struct libztex_device *newdev; int i, cnt, err; unsigned char buf[64]; + uint16_t langid; newdev = malloc(sizeof(struct libztex_device)); newdev->bitFileName = NULL; @@ -436,13 +437,40 @@ int libztex_prepare_device(struct libusb_device *dev, struct libztex_device** zt return err; } - cnt = libusb_get_string_descriptor_ascii (newdev->hndl, newdev->descriptor.iSerialNumber, newdev->snString, - LIBZTEX_SNSTRING_LEN + 1); + /* We open code string descriptor retrieval and ASCII decoding here + * in order to work around that libusb_get_string_descriptor_ascii() + * in the FreeBSD libusb implementation hits a bug in ZTEX firmware, + * where the device returns more bytes than requested, causing babble, + * which makes FreeBSD return an error to us. + * + * Avoid the mess by doing it manually the same way as libusb-1.0. + */ + + cnt = libusb_control_transfer(newdev->hndl, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_STRING << 8) | 0, + 0x0000, buf, sizeof(buf), 1000); + if (unlikely(cnt < 0)) { + applog(LOG_ERR, "Ztex check device: Failed to read device LANGIDs with err %d", cnt); + return cnt; + } + + langid = libusb_le16_to_cpu(((uint16_t *)buf)[1]); + + cnt = libusb_control_transfer(newdev->hndl, LIBUSB_ENDPOINT_IN, + LIBUSB_REQUEST_GET_DESCRIPTOR, + (LIBUSB_DT_STRING << 8) | newdev->descriptor.iSerialNumber, + langid, buf, sizeof(buf), 1000); if (unlikely(cnt < 0)) { applog(LOG_ERR, "Ztex check device: Failed to read device snString with err %d", cnt); return cnt; } + /* num chars = (all bytes except bLength and bDescriptorType) / 2 */ + for (i = 0; i <= (cnt - 2) / 2 && i < sizeof(newdev->snString)-1; i++) + newdev->snString[i] = buf[2 + i*2]; + + newdev->snString[i] = 0; + cnt = libusb_control_transfer(newdev->hndl, 0xc0, 0x22, 0, 0, buf, 40, 500); if (unlikely(cnt < 0)) { applog(LOG_ERR, "Ztex check device: Failed to read ztex descriptor with err %d", cnt);