From b1a3b012ddb497e606afa0ae955aabc116eb4d46 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 22 Sep 2013 23:16:21 +1000 Subject: [PATCH 01/88] pool_active uninitialised_var rolltime --- cgminer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index a3e85710..1677790e 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5571,7 +5571,7 @@ static bool pool_active(struct pool *pool, bool pinging) bool ret = false; json_t *val; CURL *curl; - int rolltime; + int uninitialised_var(rolltime); if (pool->has_gbt) applog(LOG_DEBUG, "Retrieving block template from pool %s", pool->rpc_url); From 088a340342c8a17dcab4e0edf90bfc2a8d9c712a Mon Sep 17 00:00:00 2001 From: Xiangfu Date: Sun, 22 Sep 2013 23:04:36 +0800 Subject: [PATCH 02/88] avalon: display the FPGA controller version on API --- driver-avalon.c | 16 +++++++++++++--- driver-avalon.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/driver-avalon.c b/driver-avalon.c index 348a2aea..824005e9 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -273,6 +273,7 @@ static int avalon_reset(struct cgpu_info *avalon, bool initial) struct avalon_task at; uint8_t *buf, *tmp; struct timespec p; + struct avalon_info *info = avalon->device_data; /* Send reset, then check for result */ avalon_init_task(&at, 1, 0, @@ -329,9 +330,17 @@ static int avalon_reset(struct cgpu_info *avalon, bool initial) " (%d: %02x %02x %02x %02x)", avalon->drv->name, avalon->device_id, i, buf[0], buf[1], buf[2], buf[3]); /* FIXME: return 1; */ - } else - applog(LOG_WARNING, "%s%d: Reset succeeded", - avalon->drv->name, avalon->device_id); + } else { + /* buf[44]: minor + * buf[45]: day + * buf[46]: year,month, d6: 201306 + */ + info->ctlr_ver = ((buf[46] >> 4) + 2000) * 1000000 + + (buf[46] & 0x0f) * 10000 + + buf[45] * 100 + buf[44]; + applog(LOG_WARNING, "%s%d: Reset succeeded (Controller version: %d)", + avalon->drv->name, avalon->device_id, info->ctlr_ver); + } return 0; } @@ -1522,6 +1531,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu) info->version1, info->version2, info->version3); root = api_add_string(root, "version", buf, true); } + root = api_add_int(root, "Controller Version", &(info->ctlr_ver), false); return root; } diff --git a/driver-avalon.h b/driver-avalon.h index 3f7c6960..54dc5e2b 100644 --- a/driver-avalon.h +++ b/driver-avalon.h @@ -125,6 +125,7 @@ struct avalon_info { int matching_work[AVALON_DEFAULT_MINER_NUM]; int frequency; + uint32_t ctlr_ver; struct thr_info *thr; pthread_t read_thr; From a8f0418c2c7be17295db2b3894b31f9f6589f5e9 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 23 Sep 2013 09:33:41 +1000 Subject: [PATCH 03/88] Add redfury device to udev rules. --- 01-cgminer.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/01-cgminer.rules b/01-cgminer.rules index f3a488a1..24211b49 100644 --- a/01-cgminer.rules +++ b/01-cgminer.rules @@ -18,3 +18,6 @@ ATTRS{idVendor}=="067b", ATTRS{idProduct}=="0230", SUBSYSTEMS=="usb", ACTION=="a # Ztex ATTRS{idVendor}=="221a", ATTRS{idProduct}=="0100", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" + +# BF1 +ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" From 8862cf9f07eff4a8777ee272bab3b2c65434fba7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 20:18:11 +1000 Subject: [PATCH 04/88] Add basic defines for building for bitfury devices. --- configure.ac | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 0b6c9ba0..24e68729 100644 --- a/configure.ac +++ b/configure.ac @@ -242,6 +242,17 @@ if test "x$bitforce" = xyes; then fi AM_CONDITIONAL([HAS_BITFORCE], [test x$bitforce = xyes]) +bitfury="no" + +AC_ARG_ENABLE([bitfury], + [AC_HELP_STRING([--enable-bitfury],[Compile support for BitFury ASICs (default disabled)])], + [bitfury=$enableval] + ) +if test "x$bitfury" = xyes; then + AC_DEFINE([USE_BITFURY], [1], [Defined to 1 if BitForce support is wanted]) +fi +AM_CONDITIONAL([HAS_BITFURY], [test x$bitfury = xyes]) + icarus="no" AC_ARG_ENABLE([icarus], @@ -310,7 +321,7 @@ else ]) fi -if test x$avalon$bitforce$modminer$bflsc$icarus != xnonononono; then +if test x$avalon$bitforce$bitfury$modminer$bflsc$icarus != xnononononono; then want_usbutils=true else want_usbutils=false @@ -482,14 +493,14 @@ if test "x$opencl" != xno; then else echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED" - if test "x$bitforce$avalon$icarus$ztex$modminer$bflsc" = xnononononono; then + if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc" = xnonononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" fi else echo " OpenCL...............: Detection overrided. GPU mining support DISABLED" - if test "x$bitforce$icarus$avalon$ztex$modminer$bflsc" = xnononononono; then + if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc" = xnonononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" @@ -524,6 +535,12 @@ else echo " BitForce.FPGAs.......: Disabled" fi +if test "x$bitfury" = xyes; then + echo " BitFury.ASICs........: Enabled" +else + echo " BitFury.ASICs........: Disabled" +fi + if test "x$icarus" = xyes; then echo " Icarus.FPGAs.........: Enabled" else From 99c838965eaa0df047a3a7982cf80de2de606402 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 20:39:59 +1000 Subject: [PATCH 05/88] Add bf1 device information to usbutils to enable device detection. --- usbutils.c | 32 ++++++++++++++++++++++++++++++++ usbutils.h | 1 + 2 files changed, 33 insertions(+) diff --git a/usbutils.c b/usbutils.c index f8399a2f..4ce1c33d 100644 --- a/usbutils.c +++ b/usbutils.c @@ -66,6 +66,10 @@ #define DRV_AVALON 6 #endif +#ifdef USE_BITFURY +#define DRV_BITFURY 8 +#endif + #define DRV_LAST -1 #define USB_CONFIG 1 @@ -73,12 +77,14 @@ #ifdef WIN32 #define BFLSC_TIMEOUT_MS 999 #define BITFORCE_TIMEOUT_MS 999 +#define BITFURY_TIMEOUT_MS 999 #define MODMINER_TIMEOUT_MS 999 #define AVALON_TIMEOUT_MS 999 #define ICARUS_TIMEOUT_MS 999 #else #define BFLSC_TIMEOUT_MS 300 #define BITFORCE_TIMEOUT_MS 200 +#define BITFURY_TIMEOUT_MS 200 #define MODMINER_TIMEOUT_MS 100 #define AVALON_TIMEOUT_MS 200 #define ICARUS_TIMEOUT_MS 200 @@ -116,6 +122,17 @@ static struct usb_intinfo bfl_ints[] = { }; #endif +#ifdef USE_BITFURY +static struct usb_epinfo bfu_epinfos[] = { + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 } +}; + +static struct usb_intinfo bfu_ints[] = { + USB_EPS(1, bfu_epinfos) +}; +#endif + #ifdef USE_MODMINER static struct usb_epinfo mmq_epinfos[] = { { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, @@ -246,6 +263,21 @@ static struct usb_find_devices find_dev[] = { .latency = LATENCY_STD, INTINFO(bfl_ints) }, #endif +#ifdef USE_BITFURY + { + .drv = DRV_BITFURY, + .name = "BFO", + .ident = IDENT_BFU, + .idVendor = 0x03eb, + .idProduct = 0x204b, + .config = 1, + .timeout = BITFURY_TIMEOUT_MS, + .latency = LATENCY_UNUSED, + .iManufacturer = "BPMC", + .iProduct = "Bitfury BF1", + INTINFO(bfu_ints) + }, +#endif #ifdef USE_MODMINER { .drv = DRV_MODMINER, diff --git a/usbutils.h b/usbutils.h index 779c0570..05a7b676 100644 --- a/usbutils.h +++ b/usbutils.h @@ -134,6 +134,7 @@ enum sub_ident { IDENT_BAS, IDENT_BAM, IDENT_BFL, + IDENT_BFU, IDENT_MMQ, IDENT_AVA, IDENT_BTB, From 68a7e21022cdab025095bfb36bd5dc8813fdce77 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 20:59:10 +1000 Subject: [PATCH 06/88] Create basic placeholders for bitfury driver code. --- Makefile.am | 4 +++ driver-bitfury.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ driver-bitfury.h | 15 ++++++++++ miner.h | 1 + 4 files changed, 93 insertions(+) create mode 100644 driver-bitfury.c create mode 100644 driver-bitfury.h diff --git a/Makefile.am b/Makefile.am index 706ebed7..2389d670 100644 --- a/Makefile.am +++ b/Makefile.am @@ -76,6 +76,10 @@ if HAS_BITFORCE cgminer_SOURCES += driver-bitforce.c endif +if HAS_BITFURY +cgminer_SOURCES += driver-bitfury.c driver-bitfury.h +endif + if HAS_ICARUS cgminer_SOURCES += driver-icarus.c endif diff --git a/driver-bitfury.c b/driver-bitfury.c new file mode 100644 index 00000000..aad2501a --- /dev/null +++ b/driver-bitfury.c @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Con Kolivas + * + * 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 3 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include "config.h" + +#include "miner.h" +#include "driver-bitfury.h" + +struct device_drv bitfury_drv; + +static void bitfury_detect(void) +{ +} + +static bool bitfury_prepare(struct thr_info __maybe_unused *thr) +{ + return false; +} + +static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) +{ + return true; +} + +static int64_t bitfury_scanhash(struct thr_info __maybe_unused *thr) +{ + return 0; +} + +static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury) +{ +} + +static struct api_data *bitfury_api_stats(struct cgpu_info __maybe_unused *cgpu) +{ + return NULL; +} + +static void get_bitfury_statline_before(char __maybe_unused *buf, size_t __maybe_unused bufsiz, + struct cgpu_info __maybe_unused *bitfury) +{ +} + +static void bitfury_init(struct cgpu_info __maybe_unused *bitfury) +{ +} + +static void bitfury_shutdown(struct thr_info __maybe_unused *thr) +{ +} + +/* Currently hardcoded to BF1 devices */ +struct device_drv bitfury_drv = { + .drv_id = DRIVER_BITFURY, + .dname = "bitfury", + .name = "BFO", + .drv_detect = bitfury_detect, + .thread_prepare = bitfury_prepare, + .hash_work = hash_queued_work, + .queue_full = bitfury_fill, + .scanwork = bitfury_scanhash, + .flush_work = bitfury_flush_work, + .get_api_stats = bitfury_api_stats, + .get_statline_before = get_bitfury_statline_before, + .reinit_device = bitfury_init, + .thread_shutdown = bitfury_shutdown +}; diff --git a/driver-bitfury.h b/driver-bitfury.h new file mode 100644 index 00000000..52592bb3 --- /dev/null +++ b/driver-bitfury.h @@ -0,0 +1,15 @@ +/* + * Copyright 2013 Con Kolivas + * + * 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 3 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#ifndef BITFURY_H +#define BITFURY_H + +#include "usbutils.h" + +#endif /* BITFURY_H */ diff --git a/miner.h b/miner.h index d551585e..bc10f5e1 100644 --- a/miner.h +++ b/miner.h @@ -234,6 +234,7 @@ enum drv_driver { DRIVER_OPENCL = 0, DRIVER_ICARUS, DRIVER_BITFORCE, + DRIVER_BITFURY, DRIVER_MODMINER, DRIVER_ZTEX, DRIVER_BFLSC, From 2ab023f3000d45a66f767ba9020dcd4487995500 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 21:55:47 +1000 Subject: [PATCH 07/88] Add BF1 detection code to bitfury driver. --- cgminer.c | 16 ++++++++++++++++ driver-bitfury.c | 16 ++++++++++++++++ usbutils.c | 20 ++++++++++++++++++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/cgminer.c b/cgminer.c index 1677790e..29fd52e4 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1563,6 +1563,9 @@ static char *opt_verusage_and_exit(const char *extra) #ifdef USE_BITFORCE "bitforce " #endif +#ifdef USE_BITFURY + "bitfury " +#endif #ifdef HAVE_OPENCL "GPU " #endif @@ -7352,6 +7355,10 @@ extern struct device_drv bflsc_drv; extern struct device_drv bitforce_drv; #endif +#ifdef USE_BITFURY +extern struct device_drv bitfury_drv; +#endif + #ifdef USE_ICARUS extern struct device_drv icarus_drv; #endif @@ -7650,6 +7657,10 @@ static void *hotplug_thread(void __maybe_unused *userdata) bitforce_drv.drv_detect(); #endif +#ifdef USE_BITFURY + bitfury_drv.drv_detect(); +#endif + #ifdef USE_MODMINER modminer_drv.drv_detect(); #endif @@ -7883,6 +7894,11 @@ int main(int argc, char *argv[]) bitforce_drv.drv_detect(); #endif +#ifdef USE_BITFURY + if (!opt_scrypt) + bitfury_drv.drv_detect(); +#endif + #ifdef USE_MODMINER if (!opt_scrypt) modminer_drv.drv_detect(); diff --git a/driver-bitfury.c b/driver-bitfury.c index aad2501a..f1fd3de6 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -14,8 +14,24 @@ struct device_drv bitfury_drv; +static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) +{ + struct cgpu_info *bitfury; + + bitfury = usb_alloc_cgpu(&bitfury_drv, 1); + + if (!usb_init(bitfury, dev, found)) { + bitfury = usb_free_cgpu(bitfury); + return false; + } + applog(LOG_WARNING, "%s%d: Found at %s", bitfury->drv->name, + bitfury->device_id, bitfury->device_path); + return true; +} + static void bitfury_detect(void) { + usb_detect(&bitfury_drv, bitfury_detect_one); } static bool bitfury_prepare(struct thr_info __maybe_unused *thr) diff --git a/usbutils.c b/usbutils.c index 4ce1c33d..9bf0b174 100644 --- a/usbutils.c +++ b/usbutils.c @@ -124,8 +124,8 @@ static struct usb_intinfo bfl_ints[] = { #ifdef USE_BITFURY static struct usb_epinfo bfu_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0 } }; static struct usb_intinfo bfu_ints[] = { @@ -407,6 +407,10 @@ extern struct device_drv bflsc_drv; extern struct device_drv bitforce_drv; #endif +#ifdef USE_BITFURY +extern struct device_drv bitfury_drv; +#endif + #ifdef USE_MODMINER extern struct device_drv modminer_drv; #endif @@ -2092,6 +2096,11 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, return usb_check_each(DRV_BITFORCE, drv, dev); #endif +#ifdef USE_BITFURY + if (drv->drv_id == DRIVER_BITFURY) + return usb_check_each(DRV_BITFURY, drv, dev); +#endif + #ifdef USE_MODMINER if (drv->drv_id == DRIVER_MODMINER) return usb_check_each(DRV_MODMINER, drv, dev); @@ -3304,6 +3313,7 @@ void usb_cleanup() switch (cgpu->drv->drv_id) { case DRIVER_BFLSC: case DRIVER_BITFORCE: + case DRIVER_BITFURY: case DRIVER_MODMINER: case DRIVER_ICARUS: case DRIVER_AVALON: @@ -3443,6 +3453,12 @@ void usb_initialise() found = true; } #endif +#ifdef USE_BITFURY + if (!found && strcasecmp(ptr, bitfury_drv.name) == 0) { + drv_count[bitfury_drv.drv_id].limit = lim; + found = true; + } +#endif #ifdef USE_MODMINER if (!found && strcasecmp(ptr, modminer_drv.name) == 0) { drv_count[modminer_drv.drv_id].limit = lim; From 9a3684b809776b30e9f841ef7b29600cb46ddb5a Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 22:16:31 +1000 Subject: [PATCH 08/88] Add magic BF1 bitfury open and close control sequences. --- driver-bitfury.c | 26 +++++++++++++++++++++++++- usbutils.h | 4 +++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index f1fd3de6..6ec794a9 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -14,6 +14,23 @@ struct device_drv bitfury_drv; +static void bitfury_open(struct cgpu_info *bitfury) +{ + /* Magic open sequence */ + usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BFO_OPEN); +} + +static void bitfury_close(struct cgpu_info *bitfury) +{ + /* Magic close sequence */ + usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BFO_CLOSE); +} + +static void bitfury_initialise(struct cgpu_info *bitfury) +{ + bitfury_open(bitfury); +} + static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *bitfury; @@ -26,7 +43,11 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device } applog(LOG_WARNING, "%s%d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); - return true; + + bitfury_initialise(bitfury); + + bitfury_close(bitfury); + return false; } static void bitfury_detect(void) @@ -69,6 +90,9 @@ static void bitfury_init(struct cgpu_info __maybe_unused *bitfury) static void bitfury_shutdown(struct thr_info __maybe_unused *thr) { + struct cgpu_info *bitfury = thr->cgpu; + + bitfury_close(bitfury); } /* Currently hardcoded to BF1 devices */ diff --git a/usbutils.h b/usbutils.h index 05a7b676..29501e2b 100644 --- a/usbutils.h +++ b/usbutils.h @@ -321,7 +321,9 @@ struct cg_usb_info { USB_ADD_COMMAND(C_FTDI_STATUS, "FTDIStatus") \ USB_ADD_COMMAND(C_ENABLE_UART, "EnableUART") \ USB_ADD_COMMAND(C_BB_SET_VOLTAGE, "SetCoreVoltage") \ - USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") + USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") \ + USB_ADD_COMMAND(C_BFO_OPEN, "BF1Open") \ + USB_ADD_COMMAND(C_BFO_CLOSE, "BF1Close") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ #define USB_ADD_COMMAND(X, Y) X, From 54ac35553fa7d1509f3082b2553e8e1f4ab11ace Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 22:28:56 +1000 Subject: [PATCH 09/88] Add commands for getting BF1 bitfury info --- driver-bitfury.c | 26 ++++++++++++++++++-------- usbutils.h | 6 +++++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 6ec794a9..66f35ff5 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -26,27 +26,37 @@ static void bitfury_close(struct cgpu_info *bitfury) usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BFO_CLOSE); } -static void bitfury_initialise(struct cgpu_info *bitfury) -{ - bitfury_open(bitfury); -} - static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *bitfury; + char buf[512]; + int amount; bitfury = usb_alloc_cgpu(&bitfury_drv, 1); if (!usb_init(bitfury, dev, found)) { bitfury = usb_free_cgpu(bitfury); - return false; + goto out; } - applog(LOG_WARNING, "%s%d: Found at %s", bitfury->drv->name, + applog(LOG_INFO, "%s%d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); - bitfury_initialise(bitfury); + usb_buffer_enable(bitfury); + bitfury_open(bitfury); + usb_write(bitfury, "I", 1, &amount, C_BFO_REQINFO); + usb_read(bitfury, buf, 14, &amount, C_BFO_GETINFO); + if (amount != 14) { + applog(LOG_WARNING, "%s%d: Getinfo received %d", + bitfury->drv->name, bitfury->device_id, amount); + goto out_close; + } + applog(LOG_INFO, "%s%d: Getinfo returned %s", bitfury->drv->name, + bitfury->device_id, buf); + //return true; +out_close: bitfury_close(bitfury); +out: return false; } diff --git a/usbutils.h b/usbutils.h index 29501e2b..3119e4a3 100644 --- a/usbutils.h +++ b/usbutils.h @@ -323,7 +323,11 @@ struct cg_usb_info { USB_ADD_COMMAND(C_BB_SET_VOLTAGE, "SetCoreVoltage") \ USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") \ USB_ADD_COMMAND(C_BFO_OPEN, "BF1Open") \ - USB_ADD_COMMAND(C_BFO_CLOSE, "BF1Close") + USB_ADD_COMMAND(C_BFO_CLOSE, "BF1Close") \ + USB_ADD_COMMAND(C_BFO_REQINFO, "BF1RequestInfo") \ + USB_ADD_COMMAND(C_BFO_GETINFO, "BF1GetInfo") \ + USB_ADD_COMMAND(C_BFO_REQRESET, "BF1RequestReset") \ + USB_ADD_COMMAND(C_BFO_GETRESET, "BF1GetReset") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ #define USB_ADD_COMMAND(X, Y) X, From 977a7b753f0a7cc5e24d57d5366aae02ab8b8415 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 22:58:10 +1000 Subject: [PATCH 10/88] Reliably extract BF1 information at startup and reset the device. --- driver-bitfury.c | 42 ++++++++++++++++++++++++++++++++++++++++-- driver-bitfury.h | 6 ++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 66f35ff5..81c3ef0a 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -26,9 +26,20 @@ static void bitfury_close(struct cgpu_info *bitfury) usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BFO_CLOSE); } +static void bitfury_empty_buffer(struct cgpu_info *bitfury) +{ + char buf[512]; + int amount; + + do { + usb_read(bitfury, buf, 512, &amount, C_PING); + } while (amount); +} + static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *bitfury; + struct bitfury_info *info; char buf[512]; int amount; @@ -41,17 +52,44 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device applog(LOG_INFO, "%s%d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); + info = calloc(sizeof(struct bitfury_info), 1); + if (!info) + quit(1, "Failed to calloc info in bitfury_detect_one"); + bitfury->device_data = info; + + bitfury_empty_buffer(bitfury); usb_buffer_enable(bitfury); + bitfury_open(bitfury); + + /* Send getinfo request */ usb_write(bitfury, "I", 1, &amount, C_BFO_REQINFO); usb_read(bitfury, buf, 14, &amount, C_BFO_GETINFO); if (amount != 14) { - applog(LOG_WARNING, "%s%d: Getinfo received %d", + applog(LOG_WARNING, "%s%d: Getinfo received %d bytes", + bitfury->drv->name, bitfury->device_id, amount); + goto out_close; + } + info->version = buf[1]; + memcpy(&info->product, buf + 2, 8); + memcpy(&info->serial, buf + 10, 4); + + applog(LOG_INFO, "%s%d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name, + bitfury->device_id, info->version, info->product, info->serial); + bitfury_empty_buffer(bitfury); + + /* Send reset request */ + usb_write(bitfury, "R", 1, &amount, C_BFO_REQRESET); + usb_read_timeout(bitfury, buf, 7, &amount, 1000, C_BFO_GETRESET); + + if (amount != 7) { + applog(LOG_WARNING, "%s%d: Getreset received %d bytes", bitfury->drv->name, bitfury->device_id, amount); goto out_close; } - applog(LOG_INFO, "%s%d: Getinfo returned %s", bitfury->drv->name, + applog(LOG_INFO, "%s%d: Getreset returned %s", bitfury->drv->name, bitfury->device_id, buf); + bitfury_empty_buffer(bitfury); //return true; out_close: diff --git a/driver-bitfury.h b/driver-bitfury.h index 52592bb3..c427fdc8 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -12,4 +12,10 @@ #include "usbutils.h" +struct bitfury_info { + uint8_t version; + char product[8]; + uint32_t serial; +}; + #endif /* BITFURY_H */ From 4fb802fc58debc5e1c8ead2b2a9700b1723a8716 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 24 Sep 2013 23:30:01 +1000 Subject: [PATCH 11/88] Provide a bitfury identify function for bf1. --- driver-bitfury.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 81c3ef0a..c039e7a1 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -36,6 +36,13 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) } while (amount); } +static void bitfury_identify(struct cgpu_info *bitfury) +{ + int amount; + + usb_write(bitfury, "L", 1, &amount, C_PING); +} + static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *bitfury; @@ -91,6 +98,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury->device_id, buf); bitfury_empty_buffer(bitfury); + bitfury_identify(bitfury); + bitfury_empty_buffer(bitfury); //return true; out_close: bitfury_close(bitfury); @@ -157,5 +166,6 @@ struct device_drv bitfury_drv = { .get_api_stats = bitfury_api_stats, .get_statline_before = get_bitfury_statline_before, .reinit_device = bitfury_init, - .thread_shutdown = bitfury_shutdown + .thread_shutdown = bitfury_shutdown, + .identify_device = bitfury_identify }; From f6e475d4fbb789b8870815d6e5b8238e3a2b2f1c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 00:23:50 +1000 Subject: [PATCH 12/88] Add complete close sequence to bf1 as it happens on serial. --- driver-bitfury.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index c039e7a1..356a69d2 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -14,26 +14,30 @@ struct device_drv bitfury_drv; +static void bitfury_empty_buffer(struct cgpu_info *bitfury) +{ + char buf[512]; + int amount; + + do { + usb_read(bitfury, buf, 512, &amount, C_PING); + } while (amount); +} + static void bitfury_open(struct cgpu_info *bitfury) { /* Magic open sequence */ usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BFO_OPEN); + bitfury_empty_buffer(bitfury); } static void bitfury_close(struct cgpu_info *bitfury) { /* Magic close sequence */ usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BFO_CLOSE); -} - -static void bitfury_empty_buffer(struct cgpu_info *bitfury) -{ - char buf[512]; - int amount; - - do { - usb_read(bitfury, buf, 512, &amount, C_PING); - } while (amount); + bitfury_empty_buffer(bitfury); + usb_transfer(bitfury, 0x23, 0x08, 0x9053, 1, C_BFO_CLOSE); + bitfury_empty_buffer(bitfury); } static void bitfury_identify(struct cgpu_info *bitfury) @@ -64,7 +68,6 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device quit(1, "Failed to calloc info in bitfury_detect_one"); bitfury->device_data = info; - bitfury_empty_buffer(bitfury); usb_buffer_enable(bitfury); bitfury_open(bitfury); From 759e82bb9899a1be12300d1d756be15b1cf86a5e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 15:30:54 +1000 Subject: [PATCH 13/88] Add in first draft for a serialised work model sending/receiving data for BF1 devices. --- cgminer.c | 17 ++++++ driver-bitfury.c | 149 ++++++++++++++++++++++++++++++++++++++++++++--- driver-bitfury.h | 3 + miner.h | 1 + usbutils.c | 2 +- 5 files changed, 163 insertions(+), 9 deletions(-) diff --git a/cgminer.c b/cgminer.c index 29fd52e4..08a9abd6 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6016,6 +6016,23 @@ void inc_hw_errors(struct thr_info *thr) thr->cgpu->drv->hw_error(thr); } +bool test_nonce(struct work *work, uint32_t nonce) +{ + uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12); + unsigned char hash2[32]; + uint32_t *hash2_32 = (uint32_t *)hash2; + uint32_t diff1targ; + + *work_nonce = htole32(nonce); + + /* Do one last check before attempting to submit the work */ + rebuild_hash(work); + flip32(hash2_32, work->hash); + + diff1targ = opt_scrypt ? 0x0000ffffUL : 0; + return (be32toh(hash2_32[7] <= diff1targ)); +} + /* Returns true if nonce for work was a valid share */ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) { diff --git a/driver-bitfury.c b/driver-bitfury.c index c039e7a1..e4dabf49 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -11,6 +11,7 @@ #include "miner.h" #include "driver-bitfury.h" +#include "sha2.h" struct device_drv bitfury_drv; @@ -100,7 +101,13 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury_identify(bitfury); bitfury_empty_buffer(bitfury); - //return true; + + if (!add_cgpu(bitfury)) + goto out_close; + update_usb_stats(bitfury); + applog(LOG_INFO, "%s%d: Found at %s", + bitfury->drv->name, bitfury->device_id, bitfury->device_path); + return true; out_close: bitfury_close(bitfury); out: @@ -114,7 +121,7 @@ static void bitfury_detect(void) static bool bitfury_prepare(struct thr_info __maybe_unused *thr) { - return false; + return true; } static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) @@ -122,9 +129,137 @@ static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) return true; } -static int64_t bitfury_scanhash(struct thr_info __maybe_unused *thr) +static bool rehash(unsigned char *midstate, unsigned m7, unsigned ntime, unsigned nbits, unsigned nnonce) +{ + uint8_t in[16]; + uint32_t *in32 = (uint32_t *)in; + uint32_t *mid32 = (uint32_t *)midstate; + uint32_t out32[8]; + uint8_t *out = (uint8_t *) out32; + sha256_ctx ctx; + + memset( &ctx, 0, sizeof(sha256_ctx)); + memcpy(ctx.h, mid32, 8*4); + ctx.tot_len = 64; + + nnonce = bswap_32(nnonce); + in32[0] = bswap_32(m7); + in32[1] = bswap_32(ntime); + in32[2] = bswap_32(nbits); + in32[3] = nnonce; + + sha256_update(&ctx, in, 16); + sha256_final(&ctx, out); + sha256(out, 32, out); + + if (out32[7] == 0) + return true; + return false; +} + +static uint32_t decnonce(uint32_t in) +{ + uint32_t out; + + /* First part load */ + out = (in & 0xFF) << 24; in >>= 8; + + /* Byte reversal */ + in = (((in & 0xaaaaaaaa) >> 1) | ((in & 0x55555555) << 1)); + in = (((in & 0xcccccccc) >> 2) | ((in & 0x33333333) << 2)); + in = (((in & 0xf0f0f0f0) >> 4) | ((in & 0x0f0f0f0f) << 4)); + + out |= (in >> 2)&0x3FFFFF; + + /* Extraction */ + if (in & 1) out |= (1 << 23); + if (in & 2) out |= (1 << 22); + + out -= 0x800004; + return out; +} + +static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce) +{ + uint32_t nonceoff; + + if (test_nonce(work, nonce)) { + submit_nonce(thr, work, nonce); + return true; + } + nonceoff = nonce - 0x400000; + if (test_nonce(work, nonceoff)) { + submit_nonce(thr, work, nonceoff); + return true; + } + nonceoff = nonce - 0x800000; + if (test_nonce(work, nonceoff)) { + submit_nonce(thr, work, nonceoff); + return true; + } + nonceoff = nonce + 0x2800000; + if (test_nonce(work, nonceoff)) { + submit_nonce(thr, work, nonceoff); + return true; + } + nonceoff = nonce + 0x2C800000; + if (test_nonce(work, nonceoff)) { + submit_nonce(thr, work, nonceoff); + return true; + } + nonceoff = nonce + 0x400000; + if (test_nonce(work, nonceoff)) { + submit_nonce(thr, work, nonceoff); + return true; + } + return false; +} + +static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, + int64_t __maybe_unused max_nonce) { - return 0; + struct cgpu_info *bitfury = thr->cgpu; + struct bitfury_info *info = bitfury->device_data; + char sendbuf[45], buf[512]; + int64_t hashes = 0; + int amount, i, tot; + + sendbuf[0] = 'W'; + memcpy(sendbuf + 1, work->midstate, 32); + memcpy(sendbuf + 33, work->data + 64, 12); + usb_write(bitfury, sendbuf, 45, &amount, C_PING); + usb_read(bitfury, buf, 7, &amount, C_PING); + + if (unlikely(!info->prevwork)) { + info->prevwork = copy_work(work); + return 0; + } + + usb_read_once_timeout(bitfury, buf, 7, &amount, 2000, C_PING); + tot = amount; + while (amount) { + usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_PING); + tot += amount; + } + + for (i = 0; i < tot; i += 7) { + uint32_t nonce; + + /* Ignore state & switched data in results for now. */ + memcpy(&nonce, buf + i + 3, 4); + nonce = decnonce(nonce); + if (bitfury_checkresults(thr, work, nonce)) { + hashes += 0xffffffff; + continue; + } + if (bitfury_checkresults(thr, info->prevwork, nonce)) + hashes += 0xffffffff; + } + + free_work(info->prevwork); + info->prevwork = copy_work(work); + work->blk.nonce = 0xffffffff; + return hashes; } static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury) @@ -158,12 +293,10 @@ struct device_drv bitfury_drv = { .dname = "bitfury", .name = "BFO", .drv_detect = bitfury_detect, - .thread_prepare = bitfury_prepare, - .hash_work = hash_queued_work, - .queue_full = bitfury_fill, - .scanwork = bitfury_scanhash, + .scanhash = bitfury_scanhash, .flush_work = bitfury_flush_work, .get_api_stats = bitfury_api_stats, + .thread_prepare = bitfury_prepare, .get_statline_before = get_bitfury_statline_before, .reinit_device = bitfury_init, .thread_shutdown = bitfury_shutdown, diff --git a/driver-bitfury.h b/driver-bitfury.h index c427fdc8..5af2dfe5 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -10,12 +10,15 @@ #ifndef BITFURY_H #define BITFURY_H +#include "miner.h" #include "usbutils.h" struct bitfury_info { uint8_t version; char product[8]; uint32_t serial; + struct work *prevwork; + char readbuf[512]; }; #endif /* BITFURY_H */ diff --git a/miner.h b/miner.h index bc10f5e1..14562272 100644 --- a/miner.h +++ b/miner.h @@ -1356,6 +1356,7 @@ struct modminer_fpga_state { extern void get_datestamp(char *, size_t, struct timeval *); extern void inc_hw_errors(struct thr_info *thr); +extern bool test_nonce(struct work *work, uint32_t nonce); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern struct work *get_queued(struct cgpu_info *cgpu); extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); diff --git a/usbutils.c b/usbutils.c index 9bf0b174..e67cb6c6 100644 --- a/usbutils.c +++ b/usbutils.c @@ -84,7 +84,7 @@ #else #define BFLSC_TIMEOUT_MS 300 #define BITFORCE_TIMEOUT_MS 200 -#define BITFURY_TIMEOUT_MS 200 +#define BITFURY_TIMEOUT_MS 100 #define MODMINER_TIMEOUT_MS 100 #define AVALON_TIMEOUT_MS 200 #define ICARUS_TIMEOUT_MS 200 From d6949f3a9498c2e4dd8b015e5bb17a282661ca69 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 15:31:34 +1000 Subject: [PATCH 14/88] Decrease usb buffering to verbose logging. --- usbutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usbutils.c b/usbutils.c index e67cb6c6..ab5748b0 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2671,7 +2671,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int memcpy(usbdev->buffer, usbbuf + bufsiz, usbdev->bufamt); tot -= usbdev->bufamt; usbbuf[tot] = '\0'; - applog(LOG_ERR, "USB: %s%i read1 buffering %d extra bytes", + applog(LOG_INFO, "USB: %s%i read1 buffering %d extra bytes", cgpu->drv->name, cgpu->device_id, usbdev->bufamt); } From edcea78a61c5d39a59fbccdd3f0b815d04469215 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 16:28:34 +1000 Subject: [PATCH 15/88] Define a mandatory upper limit to waiting for reset and data on BF1 based on full nonce duration. --- driver-bitfury.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index e4dabf49..5cd4d8bf 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -13,6 +13,8 @@ #include "driver-bitfury.h" #include "sha2.h" +/* Wait longer 1/3 longer than it would take for a full nonce range */ +#define BF1WAIT 1600 struct device_drv bitfury_drv; static void bitfury_open(struct cgpu_info *bitfury) @@ -88,7 +90,7 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device /* Send reset request */ usb_write(bitfury, "R", 1, &amount, C_BFO_REQRESET); - usb_read_timeout(bitfury, buf, 7, &amount, 1000, C_BFO_GETRESET); + usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BFO_GETRESET); if (amount != 7) { applog(LOG_WARNING, "%s%d: Getreset received %d bytes", @@ -235,7 +237,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, return 0; } - usb_read_once_timeout(bitfury, buf, 7, &amount, 2000, C_PING); + usb_read_once_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_PING); tot = amount; while (amount) { usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_PING); From 55c6e55c84f67be11681490ca7eee0ab0dfd16e7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 16:31:37 +1000 Subject: [PATCH 16/88] Name the work request and result usb commands for BF1 --- driver-bitfury.c | 8 ++++---- usbutils.h | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 5cd4d8bf..7fa298a7 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -229,18 +229,18 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, sendbuf[0] = 'W'; memcpy(sendbuf + 1, work->midstate, 32); memcpy(sendbuf + 33, work->data + 64, 12); - usb_write(bitfury, sendbuf, 45, &amount, C_PING); - usb_read(bitfury, buf, 7, &amount, C_PING); + usb_write(bitfury, sendbuf, 45, &amount, C_BFO_REQWORK); + usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); if (unlikely(!info->prevwork)) { info->prevwork = copy_work(work); return 0; } - usb_read_once_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_PING); + usb_read_once_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BFO_GETRES); tot = amount; while (amount) { - usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_PING); + usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_BFO_GETRES); tot += amount; } diff --git a/usbutils.h b/usbutils.h index 3119e4a3..79695f4b 100644 --- a/usbutils.h +++ b/usbutils.h @@ -327,7 +327,10 @@ struct cg_usb_info { USB_ADD_COMMAND(C_BFO_REQINFO, "BF1RequestInfo") \ USB_ADD_COMMAND(C_BFO_GETINFO, "BF1GetInfo") \ USB_ADD_COMMAND(C_BFO_REQRESET, "BF1RequestReset") \ - USB_ADD_COMMAND(C_BFO_GETRESET, "BF1GetReset") + USB_ADD_COMMAND(C_BFO_GETRESET, "BF1GetReset") \ + USB_ADD_COMMAND(C_BFO_REQWORK, "BF1RequestWork") \ + USB_ADD_COMMAND(C_BFO_GETWORK, "BF1GetWork") \ + USB_ADD_COMMAND(C_BFO_GETRES, "BF1GetResults") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ #define USB_ADD_COMMAND(X, Y) X, From c65fd778737e31b559c8af6ace816a2e7ae7f245 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 20:46:42 +1000 Subject: [PATCH 17/88] Add yet another backup work for triple buffering of work in bf1 to account for extra late results returned and don't check nonce offsets which appear to never return. --- driver-bitfury.c | 57 ++++++++++++++++++------------------------------ driver-bitfury.h | 3 ++- 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 7fa298a7..a39fd9a8 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -131,34 +131,6 @@ static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) return true; } -static bool rehash(unsigned char *midstate, unsigned m7, unsigned ntime, unsigned nbits, unsigned nnonce) -{ - uint8_t in[16]; - uint32_t *in32 = (uint32_t *)in; - uint32_t *mid32 = (uint32_t *)midstate; - uint32_t out32[8]; - uint8_t *out = (uint8_t *) out32; - sha256_ctx ctx; - - memset( &ctx, 0, sizeof(sha256_ctx)); - memcpy(ctx.h, mid32, 8*4); - ctx.tot_len = 64; - - nnonce = bswap_32(nnonce); - in32[0] = bswap_32(m7); - in32[1] = bswap_32(ntime); - in32[2] = bswap_32(nbits); - in32[3] = nnonce; - - sha256_update(&ctx, in, 16); - sha256_final(&ctx, out); - sha256(out, 32, out); - - if (out32[7] == 0) - return true; - return false; -} - static uint32_t decnonce(uint32_t in) { uint32_t out; @@ -199,21 +171,26 @@ static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32 submit_nonce(thr, work, nonceoff); return true; } - nonceoff = nonce + 0x2800000; +#if 0 + nonceoff = nonce + 0x2800000u; if (test_nonce(work, nonceoff)) { + applog(LOG_ERR, "0x2800000"); submit_nonce(thr, work, nonceoff); return true; } - nonceoff = nonce + 0x2C800000; + nonceoff = nonce + 0x2C00000u; if (test_nonce(work, nonceoff)) { + applog(LOG_ERR, "0x2C00000"); submit_nonce(thr, work, nonceoff); return true; } - nonceoff = nonce + 0x400000; + nonceoff = nonce + 0x400000u; if (test_nonce(work, nonceoff)) { + applog(LOG_ERR, "0x400000"); submit_nonce(thr, work, nonceoff); return true; } +#endif return false; } @@ -232,8 +209,9 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, usb_write(bitfury, sendbuf, 45, &amount, C_BFO_REQWORK); usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); - if (unlikely(!info->prevwork)) { - info->prevwork = copy_work(work); + if (unlikely(!info->prevwork1)) { + info->prevwork1 = copy_work(work); + info->prevwork2 = copy_work(work); return 0; } @@ -250,16 +228,23 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, /* Ignore state & switched data in results for now. */ memcpy(&nonce, buf + i + 3, 4); nonce = decnonce(nonce); + if (bitfury_checkresults(thr, info->prevwork1, nonce)) { + hashes += 0xffffffff; + continue; + } if (bitfury_checkresults(thr, work, nonce)) { hashes += 0xffffffff; continue; } - if (bitfury_checkresults(thr, info->prevwork, nonce)) + if (bitfury_checkresults(thr, info->prevwork2, nonce)) { hashes += 0xffffffff; + continue; + } } - free_work(info->prevwork); - info->prevwork = copy_work(work); + free_work(info->prevwork2); + info->prevwork2 = info->prevwork1; + info->prevwork1 = copy_work(work); work->blk.nonce = 0xffffffff; return hashes; } diff --git a/driver-bitfury.h b/driver-bitfury.h index 5af2dfe5..6baa94fc 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -17,7 +17,8 @@ struct bitfury_info { uint8_t version; char product[8]; uint32_t serial; - struct work *prevwork; + struct work *prevwork1; + struct work *prevwork2; char readbuf[512]; }; From 4507a3803b7a1040fbc63573728813442dcbbef1 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 22:12:34 +1000 Subject: [PATCH 18/88] Optimise inner scanhash loop for bf1. --- driver-bitfury.c | 54 ++++++++++++++++++++++++++++-------------------- driver-bitfury.h | 3 ++- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index a39fd9a8..58839adf 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -199,50 +199,60 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, { struct cgpu_info *bitfury = thr->cgpu; struct bitfury_info *info = bitfury->device_data; - char sendbuf[45], buf[512]; int64_t hashes = 0; - int amount, i, tot; + char buf[45]; + int amount, i; + + buf[0] = 'W'; + memcpy(buf + 1, work->midstate, 32); + memcpy(buf + 33, work->data + 64, 12); + + /* New results may spill out from the latest work, making us drop out + * too early so read whatever we get for the first half nonce and then + * look for the results to prev work. */ + usb_read_timeout(bitfury, info->buf, 512, &info->tot, 600, C_BFO_GETRES); + + /* Now look for the bulk of the previous work results, they will come + * in a batch following the first data. */ + usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, 1000, C_BFO_GETRES); + info->tot += amount; + while (amount) { + usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BFO_GETRES); + info->tot += amount; + }; - sendbuf[0] = 'W'; - memcpy(sendbuf + 1, work->midstate, 32); - memcpy(sendbuf + 33, work->data + 64, 12); - usb_write(bitfury, sendbuf, 45, &amount, C_BFO_REQWORK); + /* Send work */ + usb_write(bitfury, buf, 45, &amount, C_BFO_REQWORK); + /* Get response acknowledging work */ usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); - if (unlikely(!info->prevwork1)) { - info->prevwork1 = copy_work(work); - info->prevwork2 = copy_work(work); - return 0; - } - - usb_read_once_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BFO_GETRES); - tot = amount; - while (amount) { - usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_BFO_GETRES); - tot += amount; - } + /* Only happens on startup */ + if (unlikely(!info->prevwork2)) + goto cascade; - for (i = 0; i < tot; i += 7) { + /* Search for what work the nonce matches in order of likelihood. */ + for (i = 0; i < info->tot; i += 7) { uint32_t nonce; /* Ignore state & switched data in results for now. */ - memcpy(&nonce, buf + i + 3, 4); + memcpy(&nonce, info->buf + i + 3, 4); nonce = decnonce(nonce); if (bitfury_checkresults(thr, info->prevwork1, nonce)) { hashes += 0xffffffff; continue; } - if (bitfury_checkresults(thr, work, nonce)) { + if (bitfury_checkresults(thr, info->prevwork2, nonce)) { hashes += 0xffffffff; continue; } - if (bitfury_checkresults(thr, info->prevwork2, nonce)) { + if (bitfury_checkresults(thr, work, nonce)) { hashes += 0xffffffff; continue; } } free_work(info->prevwork2); +cascade: info->prevwork2 = info->prevwork1; info->prevwork1 = copy_work(work); work->blk.nonce = 0xffffffff; diff --git a/driver-bitfury.h b/driver-bitfury.h index 6baa94fc..96ec889b 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -19,7 +19,8 @@ struct bitfury_info { uint32_t serial; struct work *prevwork1; struct work *prevwork2; - char readbuf[512]; + char buf[512]; + int tot; }; #endif /* BITFURY_H */ From 5a8ac9fdafbfa3dcaf6415d8e5c250705be6fefb Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 22:22:05 +1000 Subject: [PATCH 19/88] Meter out return of estimated hashes in BF1 to smooth out visible hashrate. --- driver-bitfury.c | 15 +++++++++------ driver-bitfury.h | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 58839adf..d56b80b8 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -199,9 +199,8 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, { struct cgpu_info *bitfury = thr->cgpu; struct bitfury_info *info = bitfury->device_data; - int64_t hashes = 0; - char buf[45]; int amount, i; + char buf[45]; buf[0] = 'W'; memcpy(buf + 1, work->midstate, 32); @@ -238,15 +237,15 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, memcpy(&nonce, info->buf + i + 3, 4); nonce = decnonce(nonce); if (bitfury_checkresults(thr, info->prevwork1, nonce)) { - hashes += 0xffffffff; + info->nonces++; continue; } if (bitfury_checkresults(thr, info->prevwork2, nonce)) { - hashes += 0xffffffff; + info->nonces++; continue; } if (bitfury_checkresults(thr, work, nonce)) { - hashes += 0xffffffff; + info->nonces++; continue; } } @@ -256,7 +255,11 @@ cascade: info->prevwork2 = info->prevwork1; info->prevwork1 = copy_work(work); work->blk.nonce = 0xffffffff; - return hashes; + if (info->nonces) { + info->nonces--; + return (int64_t)0xffffffff; + } + return 0; } static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury) diff --git a/driver-bitfury.h b/driver-bitfury.h index 96ec889b..72bc2673 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -21,6 +21,7 @@ struct bitfury_info { struct work *prevwork2; char buf[512]; int tot; + int nonces; }; #endif /* BITFURY_H */ From 7a9669ec3c36714e0a7117593cfeb931a5e6780c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 22:43:39 +1000 Subject: [PATCH 20/88] Remove unused code by bitfury driver since current driver uses serialised scanhash. --- driver-bitfury.c | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index d56b80b8..7559d7ea 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -121,16 +121,6 @@ static void bitfury_detect(void) usb_detect(&bitfury_drv, bitfury_detect_one); } -static bool bitfury_prepare(struct thr_info __maybe_unused *thr) -{ - return true; -} - -static bool bitfury_fill(struct cgpu_info __maybe_unused *bitfury) -{ - return true; -} - static uint32_t decnonce(uint32_t in) { uint32_t out; @@ -171,26 +161,6 @@ static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32 submit_nonce(thr, work, nonceoff); return true; } -#if 0 - nonceoff = nonce + 0x2800000u; - if (test_nonce(work, nonceoff)) { - applog(LOG_ERR, "0x2800000"); - submit_nonce(thr, work, nonceoff); - return true; - } - nonceoff = nonce + 0x2C00000u; - if (test_nonce(work, nonceoff)) { - applog(LOG_ERR, "0x2C00000"); - submit_nonce(thr, work, nonceoff); - return true; - } - nonceoff = nonce + 0x400000u; - if (test_nonce(work, nonceoff)) { - applog(LOG_ERR, "0x400000"); - submit_nonce(thr, work, nonceoff); - return true; - } -#endif return false; } @@ -262,20 +232,11 @@ cascade: return 0; } -static void bitfury_flush_work(struct cgpu_info __maybe_unused *bitfury) -{ -} - static struct api_data *bitfury_api_stats(struct cgpu_info __maybe_unused *cgpu) { return NULL; } -static void get_bitfury_statline_before(char __maybe_unused *buf, size_t __maybe_unused bufsiz, - struct cgpu_info __maybe_unused *bitfury) -{ -} - static void bitfury_init(struct cgpu_info __maybe_unused *bitfury) { } @@ -294,10 +255,7 @@ struct device_drv bitfury_drv = { .name = "BFO", .drv_detect = bitfury_detect, .scanhash = bitfury_scanhash, - .flush_work = bitfury_flush_work, .get_api_stats = bitfury_api_stats, - .thread_prepare = bitfury_prepare, - .get_statline_before = get_bitfury_statline_before, .reinit_device = bitfury_init, .thread_shutdown = bitfury_shutdown, .identify_device = bitfury_identify From 9040cac924519ca7cc1bdc21279793bc6da52c4d Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 22:47:19 +1000 Subject: [PATCH 21/88] restart_wait should return 0 if thr_restart is true. --- cgminer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 08a9abd6..43bc0030 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3844,7 +3844,7 @@ int restart_wait(struct thr_info *thr, unsigned int mstime) mutex_lock(&restart_lock); if (thr->work_restart) - rc = ETIMEDOUT; + rc = 0; else rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime); mutex_unlock(&restart_lock); From 8c0ab5f31008f2cba8680a1cae20c895f43ef4d0 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 23:18:17 +1000 Subject: [PATCH 22/88] Last result returned by BF1 is an end of results marker so ignore it. --- driver-bitfury.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 7559d7ea..5d3242e8 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -199,8 +199,9 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, if (unlikely(!info->prevwork2)) goto cascade; - /* Search for what work the nonce matches in order of likelihood. */ - for (i = 0; i < info->tot; i += 7) { + /* Search for what work the nonce matches in order of likelihood. Last + * entry is end of result marker. */ + for (i = 0; i < info->tot - 7; i += 7) { uint32_t nonce; /* Ignore state & switched data in results for now. */ From 72c779804336c9652fde3b9d97f1448c36cdd88a Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 23:30:29 +1000 Subject: [PATCH 23/88] There is no point checking for results from the next round of work on BF1. --- driver-bitfury.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 5d3242e8..e60e8a85 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -215,10 +215,6 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, info->nonces++; continue; } - if (bitfury_checkresults(thr, work, nonce)) { - info->nonces++; - continue; - } } free_work(info->prevwork2); From ff4c4779f764acdb30b6f8ddd2125e0e8267383a Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 23:33:10 +1000 Subject: [PATCH 24/88] Do not lose the first sets of results from BF1. --- driver-bitfury.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index e60e8a85..46487871 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -179,7 +179,8 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, /* New results may spill out from the latest work, making us drop out * too early so read whatever we get for the first half nonce and then * look for the results to prev work. */ - usb_read_timeout(bitfury, info->buf, 512, &info->tot, 600, C_BFO_GETRES); + usb_read_timeout(bitfury, info->buf, 512, &amount, 600, C_BFO_GETRES); + info->tot += amount; /* Now look for the bulk of the previous work results, they will come * in a batch following the first data. */ @@ -217,6 +218,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, } } + info->tot = 0; free_work(info->prevwork2); cascade: info->prevwork2 = info->prevwork1; From f97e1ad25fa9898dbaf3392731d8134b6350f94f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 25 Sep 2013 23:54:37 +1000 Subject: [PATCH 25/88] Check for work restart, breaking out early after usb reads in BF1. --- driver-bitfury.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/driver-bitfury.c b/driver-bitfury.c index 46487871..d263ecdd 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -181,6 +181,8 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, * look for the results to prev work. */ usb_read_timeout(bitfury, info->buf, 512, &amount, 600, C_BFO_GETRES); info->tot += amount; + if (unlikely(thr->work_restart)) + goto cascade; /* Now look for the bulk of the previous work results, they will come * in a batch following the first data. */ @@ -191,6 +193,9 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, info->tot += amount; }; + if (unlikely(thr->work_restart)) + goto cascade; + /* Send work */ usb_write(bitfury, buf, 45, &amount, C_BFO_REQWORK); /* Get response acknowledging work */ From 435065c86b4085aef5c079ed505584567f011fdd Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 07:24:09 +1000 Subject: [PATCH 26/88] Rename BF1 devices BF1 --- driver-bitfury.c | 24 ++++++++++++------------ usbutils.c | 2 +- usbutils.h | 18 +++++++++--------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index d263ecdd..cee285f2 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -20,13 +20,13 @@ struct device_drv bitfury_drv; static void bitfury_open(struct cgpu_info *bitfury) { /* Magic open sequence */ - usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BFO_OPEN); + usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); } static void bitfury_close(struct cgpu_info *bitfury) { /* Magic close sequence */ - usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BFO_CLOSE); + usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_CLOSE); } static void bitfury_empty_buffer(struct cgpu_info *bitfury) @@ -73,8 +73,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury_open(bitfury); /* Send getinfo request */ - usb_write(bitfury, "I", 1, &amount, C_BFO_REQINFO); - usb_read(bitfury, buf, 14, &amount, C_BFO_GETINFO); + usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); + usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); if (amount != 14) { applog(LOG_WARNING, "%s%d: Getinfo received %d bytes", bitfury->drv->name, bitfury->device_id, amount); @@ -89,8 +89,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury_empty_buffer(bitfury); /* Send reset request */ - usb_write(bitfury, "R", 1, &amount, C_BFO_REQRESET); - usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BFO_GETRESET); + usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET); + usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); if (amount != 7) { applog(LOG_WARNING, "%s%d: Getreset received %d bytes", @@ -179,17 +179,17 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, /* New results may spill out from the latest work, making us drop out * too early so read whatever we get for the first half nonce and then * look for the results to prev work. */ - usb_read_timeout(bitfury, info->buf, 512, &amount, 600, C_BFO_GETRES); + usb_read_timeout(bitfury, info->buf, 512, &amount, 600, C_BF1_GETRES); info->tot += amount; if (unlikely(thr->work_restart)) goto cascade; /* Now look for the bulk of the previous work results, they will come * in a batch following the first data. */ - usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, 1000, C_BFO_GETRES); + usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, 1000, C_BF1_GETRES); info->tot += amount; while (amount) { - usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BFO_GETRES); + usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); info->tot += amount; }; @@ -197,9 +197,9 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, goto cascade; /* Send work */ - usb_write(bitfury, buf, 45, &amount, C_BFO_REQWORK); + usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK); /* Get response acknowledging work */ - usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); + usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); /* Only happens on startup */ if (unlikely(!info->prevwork2)) @@ -256,7 +256,7 @@ static void bitfury_shutdown(struct thr_info __maybe_unused *thr) struct device_drv bitfury_drv = { .drv_id = DRIVER_BITFURY, .dname = "bitfury", - .name = "BFO", + .name = "BF1", .drv_detect = bitfury_detect, .scanhash = bitfury_scanhash, .get_api_stats = bitfury_api_stats, diff --git a/usbutils.c b/usbutils.c index ab5748b0..fe3b9cf6 100644 --- a/usbutils.c +++ b/usbutils.c @@ -266,7 +266,7 @@ static struct usb_find_devices find_dev[] = { #ifdef USE_BITFURY { .drv = DRV_BITFURY, - .name = "BFO", + .name = "BF1", .ident = IDENT_BFU, .idVendor = 0x03eb, .idProduct = 0x204b, diff --git a/usbutils.h b/usbutils.h index 79695f4b..d4b872f5 100644 --- a/usbutils.h +++ b/usbutils.h @@ -322,15 +322,15 @@ struct cg_usb_info { USB_ADD_COMMAND(C_ENABLE_UART, "EnableUART") \ USB_ADD_COMMAND(C_BB_SET_VOLTAGE, "SetCoreVoltage") \ USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") \ - USB_ADD_COMMAND(C_BFO_OPEN, "BF1Open") \ - USB_ADD_COMMAND(C_BFO_CLOSE, "BF1Close") \ - USB_ADD_COMMAND(C_BFO_REQINFO, "BF1RequestInfo") \ - USB_ADD_COMMAND(C_BFO_GETINFO, "BF1GetInfo") \ - USB_ADD_COMMAND(C_BFO_REQRESET, "BF1RequestReset") \ - USB_ADD_COMMAND(C_BFO_GETRESET, "BF1GetReset") \ - USB_ADD_COMMAND(C_BFO_REQWORK, "BF1RequestWork") \ - USB_ADD_COMMAND(C_BFO_GETWORK, "BF1GetWork") \ - USB_ADD_COMMAND(C_BFO_GETRES, "BF1GetResults") + USB_ADD_COMMAND(C_BF1_OPEN, "BF1Open") \ + USB_ADD_COMMAND(C_BF1_CLOSE, "BF1Close") \ + USB_ADD_COMMAND(C_BF1_REQINFO, "BF1RequestInfo") \ + USB_ADD_COMMAND(C_BF1_GETINFO, "BF1GetInfo") \ + USB_ADD_COMMAND(C_BF1_REQRESET, "BF1RequestReset") \ + USB_ADD_COMMAND(C_BF1_GETRESET, "BF1GetReset") \ + USB_ADD_COMMAND(C_BF1_REQWORK, "BF1RequestWork") \ + USB_ADD_COMMAND(C_BF1_GETWORK, "BF1GetWork") \ + USB_ADD_COMMAND(C_BF1_GETRES, "BF1GetResults") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ #define USB_ADD_COMMAND(X, Y) X, From 1b40d9023dc2631d915e52e27a6a14bf3a7a336c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 07:37:19 +1000 Subject: [PATCH 27/88] Abstract out the bitfury open close and reset functions and use them on reinit. --- driver-bitfury.c | 89 ++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index cee285f2..34bbfc26 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -17,6 +17,16 @@ #define BF1WAIT 1600 struct device_drv bitfury_drv; +static void bitfury_empty_buffer(struct cgpu_info *bitfury) +{ + char buf[512]; + int amount; + + do { + usb_read(bitfury, buf, 512, &amount, C_PING); + } while (amount); +} + static void bitfury_open(struct cgpu_info *bitfury) { /* Magic open sequence */ @@ -25,33 +35,63 @@ static void bitfury_open(struct cgpu_info *bitfury) static void bitfury_close(struct cgpu_info *bitfury) { + bitfury_empty_buffer(bitfury); /* Magic close sequence */ usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_CLOSE); } -static void bitfury_empty_buffer(struct cgpu_info *bitfury) +static void bitfury_identify(struct cgpu_info *bitfury) +{ + int amount; + + usb_write(bitfury, "L", 1, &amount, C_PING); +} + +static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info) { char buf[512]; int amount; - do { - usb_read(bitfury, buf, 512, &amount, C_PING); - } while (amount); + usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); + usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); + if (amount != 14) { + applog(LOG_INFO, "%s%d: Getinfo received %d bytes", + bitfury->drv->name, bitfury->device_id, amount); + return false; + } + info->version = buf[1]; + memcpy(&info->product, buf + 2, 8); + memcpy(&info->serial, buf + 10, 4); + + applog(LOG_INFO, "%s%d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name, + bitfury->device_id, info->version, info->product, info->serial); + bitfury_empty_buffer(bitfury); + return true; } -static void bitfury_identify(struct cgpu_info *bitfury) +static bool bitfury_reset(struct cgpu_info *bitfury) { + char buf[512]; int amount; - usb_write(bitfury, "L", 1, &amount, C_PING); + usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET); + usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); + + if (amount != 7) { + applog(LOG_INFO, "%s%d: Getreset received %d bytes", + bitfury->drv->name, bitfury->device_id, amount); + return false; + } + applog(LOG_INFO, "%s%d: Getreset returned %s", bitfury->drv->name, + bitfury->device_id, buf); + bitfury_empty_buffer(bitfury); + return true; } static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *bitfury; struct bitfury_info *info; - char buf[512]; - int amount; bitfury = usb_alloc_cgpu(&bitfury_drv, 1); @@ -73,39 +113,19 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury_open(bitfury); /* Send getinfo request */ - usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); - usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); - if (amount != 14) { - applog(LOG_WARNING, "%s%d: Getinfo received %d bytes", - bitfury->drv->name, bitfury->device_id, amount); + if (!bitfury_getinfo(bitfury, info)) goto out_close; - } - info->version = buf[1]; - memcpy(&info->product, buf + 2, 8); - memcpy(&info->serial, buf + 10, 4); - - applog(LOG_INFO, "%s%d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name, - bitfury->device_id, info->version, info->product, info->serial); - bitfury_empty_buffer(bitfury); /* Send reset request */ - usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET); - usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); - - if (amount != 7) { - applog(LOG_WARNING, "%s%d: Getreset received %d bytes", - bitfury->drv->name, bitfury->device_id, amount); + if (!bitfury_reset(bitfury)) goto out_close; - } - applog(LOG_INFO, "%s%d: Getreset returned %s", bitfury->drv->name, - bitfury->device_id, buf); - bitfury_empty_buffer(bitfury); bitfury_identify(bitfury); bitfury_empty_buffer(bitfury); if (!add_cgpu(bitfury)) goto out_close; + update_usb_stats(bitfury); applog(LOG_INFO, "%s%d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); @@ -241,11 +261,14 @@ static struct api_data *bitfury_api_stats(struct cgpu_info __maybe_unused *cgpu) return NULL; } -static void bitfury_init(struct cgpu_info __maybe_unused *bitfury) +static void bitfury_init(struct cgpu_info *bitfury) { + bitfury_close(bitfury); + bitfury_open(bitfury); + bitfury_reset(bitfury); } -static void bitfury_shutdown(struct thr_info __maybe_unused *thr) +static void bitfury_shutdown(struct thr_info *thr) { struct cgpu_info *bitfury = thr->cgpu; From 75333c53df012ac2a0232315a7de6d3ff8538a9e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 09:41:43 +1000 Subject: [PATCH 28/88] Space debug output for bf1 to separate from numerals. --- driver-bitfury.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 34bbfc26..f83a0035 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -55,7 +55,7 @@ static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); if (amount != 14) { - applog(LOG_INFO, "%s%d: Getinfo received %d bytes", + applog(LOG_INFO, "%s %d: Getinfo received %d bytes", bitfury->drv->name, bitfury->device_id, amount); return false; } @@ -63,7 +63,7 @@ static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info memcpy(&info->product, buf + 2, 8); memcpy(&info->serial, buf + 10, 4); - applog(LOG_INFO, "%s%d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name, + applog(LOG_INFO, "%s %d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name, bitfury->device_id, info->version, info->product, info->serial); bitfury_empty_buffer(bitfury); return true; @@ -78,11 +78,11 @@ static bool bitfury_reset(struct cgpu_info *bitfury) usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); if (amount != 7) { - applog(LOG_INFO, "%s%d: Getreset received %d bytes", + applog(LOG_INFO, "%s %d: Getreset received %d bytes", bitfury->drv->name, bitfury->device_id, amount); return false; } - applog(LOG_INFO, "%s%d: Getreset returned %s", bitfury->drv->name, + applog(LOG_INFO, "%s %d: Getreset returned %s", bitfury->drv->name, bitfury->device_id, buf); bitfury_empty_buffer(bitfury); return true; @@ -99,7 +99,7 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury = usb_free_cgpu(bitfury); goto out; } - applog(LOG_INFO, "%s%d: Found at %s", bitfury->drv->name, + applog(LOG_INFO, "%s %d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); info = calloc(sizeof(struct bitfury_info), 1); @@ -127,7 +127,7 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device goto out_close; update_usb_stats(bitfury); - applog(LOG_INFO, "%s%d: Found at %s", + applog(LOG_INFO, "%s %d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); return true; out_close: From ce285ba60262a21c4b27b207625d285852d3defd Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 11:46:09 +1000 Subject: [PATCH 29/88] Implement basic API stats for BF1 and increase array of results to check for the rare straggling result. --- api.c | 13 ++++++++++++- driver-bitfury.c | 37 ++++++++++++++++++++++++------------- driver-bitfury.h | 5 +++-- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/api.c b/api.c index c60414ff..e86ac7b9 100644 --- a/api.c +++ b/api.c @@ -29,7 +29,7 @@ #include "miner.h" #include "util.h" -#if defined(USE_BFLSC) || defined(USE_AVALON) +#if defined(USE_BFLSC) || defined(USE_AVALON) || defined(USE_BITFURY) #define HAVE_AN_ASIC 1 #endif @@ -176,6 +176,9 @@ static const char *DEVICECODE = "" #ifdef USE_BITFORCE "BFL " #endif +#ifdef USE_BITFURY + "BFU " +#endif #ifdef USE_ICARUS "ICA " #endif @@ -1223,6 +1226,10 @@ static int numascs() #ifdef USE_BFLSC if (devices[i]->drv->drv_id == DRIVER_BFLSC) count++; +#endif +#ifdef USE_BITFURY + if (devices[i]->drv->drv_id == DRIVER_BITFURY) + count++; #endif } rd_unlock(&devices_lock); @@ -1243,6 +1250,10 @@ static int ascdevice(int ascid) #ifdef USE_BFLSC if (devices[i]->drv->drv_id == DRIVER_BFLSC) count++; +#endif +#ifdef USE_BITFURY + if (devices[i]->drv->drv_id == DRIVER_BITFURY) + count++; #endif if (count == (ascid + 1)) goto foundit; diff --git a/driver-bitfury.c b/driver-bitfury.c index f83a0035..2e0b1635 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -222,32 +222,32 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); /* Only happens on startup */ - if (unlikely(!info->prevwork2)) + if (unlikely(!info->prevwork[BF1ARRAY_SIZE])) goto cascade; /* Search for what work the nonce matches in order of likelihood. Last * entry is end of result marker. */ for (i = 0; i < info->tot - 7; i += 7) { uint32_t nonce; + int j; /* Ignore state & switched data in results for now. */ memcpy(&nonce, info->buf + i + 3, 4); nonce = decnonce(nonce); - if (bitfury_checkresults(thr, info->prevwork1, nonce)) { - info->nonces++; - continue; - } - if (bitfury_checkresults(thr, info->prevwork2, nonce)) { - info->nonces++; - continue; + for (j = 0; j < BF1ARRAY_SIZE; j++) { + if (bitfury_checkresults(thr, info->prevwork[j], nonce)) { + info->nonces++; + break; + } } } info->tot = 0; - free_work(info->prevwork2); + free_work(info->prevwork[BF1ARRAY_SIZE]); cascade: - info->prevwork2 = info->prevwork1; - info->prevwork1 = copy_work(work); + for (i = BF1ARRAY_SIZE; i > 0; i--) + info->prevwork[i] = info->prevwork[i - 1]; + info->prevwork[0] = copy_work(work); work->blk.nonce = 0xffffffff; if (info->nonces) { info->nonces--; @@ -256,9 +256,20 @@ cascade: return 0; } -static struct api_data *bitfury_api_stats(struct cgpu_info __maybe_unused *cgpu) +static struct api_data *bitfury_api_stats(struct cgpu_info *cgpu) { - return NULL; + struct bitfury_info *info = cgpu->device_data; + struct api_data *root = NULL; + char serial[16]; + int version; + + version = info->version; + root = api_add_int(root, "Version", &version, true); + root = api_add_string(root, "Product", info->product, false); + sprintf(serial, "%0x", info->serial); + root = api_add_string(root, "Serial", serial, true); + + return root; } static void bitfury_init(struct cgpu_info *bitfury) diff --git a/driver-bitfury.h b/driver-bitfury.h index 72bc2673..4cc1300b 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -13,12 +13,13 @@ #include "miner.h" #include "usbutils.h" +#define BF1ARRAY_SIZE 2 + struct bitfury_info { uint8_t version; char product[8]; uint32_t serial; - struct work *prevwork1; - struct work *prevwork2; + struct work *prevwork[BF1ARRAY_SIZE + 1]; char buf[512]; int tot; int nonces; From 9dcd4e70a132bf1fe57fd6d599ae646cefd358a0 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 11:48:38 +1000 Subject: [PATCH 30/88] Minimise size of serial string we copy in BF1 stats to avoid overflow. --- driver-bitfury.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 2e0b1635..84ac35a3 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -266,7 +266,7 @@ static struct api_data *bitfury_api_stats(struct cgpu_info *cgpu) version = info->version; root = api_add_int(root, "Version", &version, true); root = api_add_string(root, "Product", info->product, false); - sprintf(serial, "%0x", info->serial); + sprintf(serial, "%08x", info->serial); root = api_add_string(root, "Serial", serial, true); return root; From 44b9cf50e3f951ca66d20d899cda63a2c6aa230f Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 12:11:25 +1000 Subject: [PATCH 31/88] Limit the duration we wait for reads in BF1 based on time already elapsed to account for other delays such as work restart messages or out of work. --- driver-bitfury.c | 18 +++++++++++++++--- driver-bitfury.h | 1 + util.c | 6 ++++++ util.h | 1 + 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 84ac35a3..b0b41a15 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -189,8 +189,10 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, { struct cgpu_info *bitfury = thr->cgpu; struct bitfury_info *info = bitfury->device_data; + struct timeval tv_now; int amount, i; char buf[45]; + int ms_diff; buf[0] = 'W'; memcpy(buf + 1, work->midstate, 32); @@ -199,14 +201,23 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, /* New results may spill out from the latest work, making us drop out * too early so read whatever we get for the first half nonce and then * look for the results to prev work. */ - usb_read_timeout(bitfury, info->buf, 512, &amount, 600, C_BF1_GETRES); - info->tot += amount; + cgtime(&tv_now); + ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start); + if (ms_diff > 0) { + usb_read_timeout(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES); + info->tot += amount; + } + if (unlikely(thr->work_restart)) goto cascade; /* Now look for the bulk of the previous work results, they will come * in a batch following the first data. */ - usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, 1000, C_BF1_GETRES); + cgtime(&tv_now); + ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start); + if (unlikely(ms_diff < 10)) + ms_diff = 10; + usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); info->tot += amount; while (amount) { usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); @@ -218,6 +229,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, /* Send work */ usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK); + cgtime(&info->tv_start); /* Get response acknowledging work */ usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); diff --git a/driver-bitfury.h b/driver-bitfury.h index 4cc1300b..db133231 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -23,6 +23,7 @@ struct bitfury_info { char buf[512]; int tot; int nonces; + struct timeval tv_start; }; #endif /* BITFURY_H */ diff --git a/util.c b/util.c index c0feaafd..ecece48d 100644 --- a/util.c +++ b/util.c @@ -1074,6 +1074,12 @@ double us_tdiff(struct timeval *end, struct timeval *start) return end->tv_sec * 1000000 + end->tv_usec - start->tv_sec * 1000000 - start->tv_usec; } +/* Returns the milliseconds difference between end and start times */ +int ms_tdiff(struct timeval *end, struct timeval *start) +{ + return end->tv_sec * 1000 + end->tv_usec / 1000 - start->tv_sec * 1000 - start->tv_usec / 1000; +} + /* Returns the seconds difference between end and start times as a double */ double tdiff(struct timeval *end, struct timeval *start) { diff --git a/util.h b/util.h index 96157fa4..5a3d9681 100644 --- a/util.h +++ b/util.h @@ -98,6 +98,7 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us); int cgtimer_to_ms(cgtimer_t *cgt); void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res); double us_tdiff(struct timeval *end, struct timeval *start); +int ms_tdiff(struct timeval *end, struct timeval *start); double tdiff(struct timeval *end, struct timeval *start); bool stratum_send(struct pool *pool, char *s, ssize_t len); bool sock_full(struct pool *pool); From fafd86313817b5dd5d4009722f73fe8730a223c7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 16:24:49 +1000 Subject: [PATCH 32/88] Use an array of offsets when checking nonces in bitfury_checkresults --- driver-bitfury.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index b0b41a15..44e90e0e 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -163,23 +163,20 @@ static uint32_t decnonce(uint32_t in) return out; } +#define BT_OFFSETS 3 +const uint32_t bf_offsets[] = {0, -0x400000, -0x800000}; + static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce) { - uint32_t nonceoff; - - if (test_nonce(work, nonce)) { - submit_nonce(thr, work, nonce); - return true; - } - nonceoff = nonce - 0x400000; - if (test_nonce(work, nonceoff)) { - submit_nonce(thr, work, nonceoff); - return true; - } - nonceoff = nonce - 0x800000; - if (test_nonce(work, nonceoff)) { - submit_nonce(thr, work, nonceoff); - return true; + uint32_t offset_nonce; + int i; + + for (i = 0; i < BT_OFFSETS; i++) { + offset_nonce = nonce + bf_offsets[i]; + if (test_nonce(work, offset_nonce)) { + submit_nonce(thr, work, offset_nonce); + return true; + } } return false; } From 3139a6c7d232177a515f4ba26691bab3f9f4bb67 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 16:36:58 +1000 Subject: [PATCH 33/88] Update ASIC-README for bitfury devices. --- ASIC-README | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/ASIC-README b/ASIC-README index e4850323..4da05ab0 100644 --- a/ASIC-README +++ b/ASIC-README @@ -1,10 +1,10 @@ SUPPORTED DEVICES Currently supported devices include the Avalon (including BitBurner), the -Butterfly Labs SC range of devices and the ASICMINER block erupters. No COM -ports on windows or TTY devices will be used by cgminer as it communicates -directly with them via USB so it is normal for them to not exist or be -disconnected when cgminer is running. +Butterfly Labs SC range of devices, the ASICMINER block erupters and the BPMC +BF1 (bitfury) USB devices. No COM ports on windows or TTY devices will be used +by cgminer as it communicates directly with them via USB so it is normal for +them to not exist or be disconnected when cgminer is running. The BFL devices should come up as one of the following: @@ -24,7 +24,18 @@ ASICMINER block erupters will come up as AMU. ASICMINER devices need the --enable-icarus option when compiling cgminer. Also note that the AMU is managed by the Icarus driver which is detailed -in the FPGA-README +in the FPGA-README. Configuring them uses the same mechanism as outlined +below for getting started with butterfly labs ASICs. + + +BITFURY devices + +Bitfury devices need the --enable-bitfury option when compiling cgminer. + +Currently only the BPMC BF1 devices AKA redfury/bluefury are supported and +come up as BF1. There are no options available for them. Bitfury device are +also set up as per the butterfly labs ASICs below. + GETTING STARTED WITH BUTTERFLY LABS ASICS From c1aba05506698b5fd78d5edd0cd2044d809a72f1 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 20:51:47 +1000 Subject: [PATCH 34/88] Only set share diff if we've confirmed it's a share first. --- cgminer.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/cgminer.c b/cgminer.c index 43bc0030..49931b66 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3658,15 +3658,6 @@ static void rebuild_hash(struct work *work) scrypt_regenhash(work); else regen_hash(work); - - work->share_diff = share_diff(work); - if (unlikely(work->share_diff >= current_diff)) { - work->block = true; - work->pool->solved++; - found_blocks++; - work->mandatory = true; - applog(LOG_NOTICE, "Found block for pool %d!", work->pool->pool_no); - } } static bool cnx_needed(struct pool *pool); @@ -6045,6 +6036,7 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) cgtime(&tv_work_found); *work_nonce = htole32(nonce); + work->share_diff = 0; /* Do one last check before attempting to submit the work */ rebuild_hash(work); @@ -6060,6 +6052,8 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) goto out; } + work->share_diff = share_diff(work); + mutex_lock(&stats_lock); total_diff1 += work->device_diff; thr->cgpu->diff1 += work->device_diff; From c4b685cbe72bf0707bc213365126b0a7840c90f9 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 26 Sep 2013 20:56:24 +1000 Subject: [PATCH 35/88] avalon stats use exact type --- driver-avalon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-avalon.c b/driver-avalon.c index 824005e9..2873bbc9 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -1531,7 +1531,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu) info->version1, info->version2, info->version3); root = api_add_string(root, "version", buf, true); } - root = api_add_int(root, "Controller Version", &(info->ctlr_ver), false); + root = api_add_uint32(root, "Controller Version", &(info->ctlr_ver), false); return root; } From 36d8653406d24a1000445744e62064c4f6203423 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 26 Sep 2013 20:58:29 +1000 Subject: [PATCH 36/88] usbutils - interfaces must all be on one handle - ep implies the interface --- driver-icarus.c | 18 ++- usbutils.c | 347 +++++++++++------------------------------------- usbutils.h | 51 ++++--- 3 files changed, 120 insertions(+), 296 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 42814a12..8ffe3908 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -177,6 +177,8 @@ static const char *MODE_VALUE_STR = "value"; static const char *MODE_UNKNOWN_STR = "unknown"; struct ICARUS_INFO { + int intinfo; + // time to calculate the golden_ob uint64_t golden_hashes; struct timeval golden_tv; @@ -277,7 +279,7 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud) usb_set_cps(icarus, baud / 10); usb_enable_cps(icarus); - interface = usb_interface(icarus); + interface = _usb_interface(icarus, info->intinfo); ident = usb_ident(icarus); switch (ident) { @@ -287,9 +289,6 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud) case IDENT_CMR2: usb_set_pps(icarus, BLT_PREF_PACKET); - if (ident == IDENT_CMR2) // Chip hack - interface++; - // Reset transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET, interface, C_RESET); @@ -434,6 +433,7 @@ static void rev(unsigned char *s, size_t l) static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct timeval *tv_start, struct timeval *tv_finish, struct thr_info *thr, int read_time) { + struct ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data); struct timeval read_start, read_finish; int err, amt; int rc = 0; @@ -446,7 +446,9 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct return ICA_NONCE_ERROR; cgtime(&read_start); - err = usb_read_timeout(icarus, (char *)buf, read_amount, &amt, ICARUS_WAIT_TIMEOUT, C_GETRESULTS); + err = usb_read_ii_timeout(icarus, info->intinfo, + (char *)buf, read_amount, &amt, + ICARUS_WAIT_TIMEOUT, C_GETRESULTS); cgtime(&read_finish); if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) { applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)", @@ -879,7 +881,7 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices struct cgpu_info *cgtmp; struct ICARUS_INFO *intmp; - cgtmp = usb_init_intinfo(icarus, i); + cgtmp = usb_copy_cgpu(icarus); if (!cgtmp) { applog(LOG_ERR, "%s%d: Init failed initinfo %d", icarus->drv->name, icarus->device_id, i); @@ -903,6 +905,8 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices // Initialise everything to match memcpy(intmp, info, sizeof(struct ICARUS_INFO)); + + intmp->intinfo = i; } } @@ -976,7 +980,7 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work, // We only want results for the work we are about to send usb_buffer_clear(icarus); - err = usb_write(icarus, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK); + err = usb_write_ii(icarus, info->intinfo, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK); if (err < 0 || amount != sizeof(ob_bin)) { applog(LOG_ERR, "%s%i: Comms error (werr=%d amt=%d)", icarus->drv->name, icarus->device_id, err, amount); diff --git a/usbutils.c b/usbutils.c index f8399a2f..2cd902fe 100644 --- a/usbutils.c +++ b/usbutils.c @@ -88,10 +88,18 @@ #define USB_EPS(_intx, _epinfosx) { \ .interface = _intx, \ + .ctrl_transfer = _intx, \ .epinfo_count = ARRAY_SIZE(_epinfosx), \ .epinfos = _epinfosx \ } +#define USB_EPS_CTRL(_inty, _ctrlinty, _epinfosy) { \ + .interface = _inty, \ + .ctrl_transfer = _ctrlinty, \ + .epinfo_count = ARRAY_SIZE(_epinfosy), \ + .epinfos = _epinfosy \ + } + #ifdef USE_BFLSC // N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 static struct usb_epinfo bas_epinfos[] = { @@ -179,7 +187,6 @@ static struct usb_epinfo cmr2_epinfos0[] = { { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } }; -#ifndef WIN32 static struct usb_epinfo cmr2_epinfos1[] = { { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 }, @@ -192,29 +199,24 @@ static struct usb_epinfo cmr2_epinfos3[] = { { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(7), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(8), 0 } }; -#endif static struct usb_intinfo cmr2_ints[] = { - USB_EPS(0, cmr2_epinfos0) -#ifndef WIN32 - , - USB_EPS(1, cmr2_epinfos1), - USB_EPS(2, cmr2_epinfos2), - USB_EPS(3, cmr2_epinfos3) -#endif + USB_EPS_CTRL(0, 1, cmr2_epinfos0), + USB_EPS_CTRL(1, 2, cmr2_epinfos1), + USB_EPS_CTRL(2, 3, cmr2_epinfos2), + USB_EPS_CTRL(3, 4, cmr2_epinfos3) }; #endif #define IDVENDOR_FTDI 0x0403 #define INTINFO(_ints) \ - .which_intinfo = 0, \ .intinfo_count = ARRAY_SIZE(_ints), \ .intinfos = _ints -#define USBEP(_usbdev, _epinfo) (_usbdev->found->intinfos[_usbdev->found->which_intinfo].epinfos[_epinfo].ep) -#define FOUNDIF(_found) (_found->intinfos[_found->which_intinfo].interface) -#define USBIF(_usbdev) FOUNDIF(_usbdev->found) +#define USBEP(_usbdev, _intinfo, _epinfo) (_usbdev->found->intinfos[_intinfo].epinfos[_epinfo].ep) +#define THISIF(_found, _this) (_found->intinfos[_this].interface) +#define USBIF(_usbdev, _this) THISIF(_usbdev->found, _this) // TODO: Add support for (at least) Isochronous endpoints static struct usb_find_devices find_dev[] = { @@ -360,11 +362,10 @@ static struct usb_find_devices find_dev[] = { .config = 1, .timeout = 100, .latency = LATENCY_UNUSED, - .which_intinfo = 0, .intinfo_count = 0, .intinfos = NULL }, #endif - { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL } + { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, NULL } }; #ifdef USE_BFLSC @@ -1269,6 +1270,8 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb) static void _usb_uninit(struct cgpu_info *cgpu) { + int ifinfo; + applog(LOG_DEBUG, "USB uninit %s%i", cgpu->drv->name, cgpu->device_id); @@ -1278,7 +1281,10 @@ static void _usb_uninit(struct cgpu_info *cgpu) return; if (cgpu->usbdev->handle) { - libusb_release_interface(cgpu->usbdev->handle, USBIF(cgpu->usbdev)); + for (ifinfo = cgpu->usbdev->found->intinfo_count - 1; ifinfo >= 0; ifinfo--) { + libusb_release_interface(cgpu->usbdev->handle, + THISIF(cgpu->usbdev->found, ifinfo)); + } cg_wlock(&cgusb_fd_lock); libusb_close(cgpu->usbdev->handle); cgpu->usbdev->handle = NULL; @@ -1306,7 +1312,7 @@ static void release_cgpu(struct cgpu_info *cgpu) { struct cg_usb_device *cgusb = cgpu->usbdev; struct cgpu_info *lookcgpu; - int which_intinfo, i; + int i; applog(LOG_DEBUG, "USB release %s%i", cgpu->drv->name, cgpu->device_id); @@ -1324,7 +1330,6 @@ static void release_cgpu(struct cgpu_info *cgpu) cgtime(&cgpu->usbinfo.last_nodev); // Any devices sharing the same USB device should be marked also - // Currently only MMQ shares a USB device for (i = 0; i < total_devices; i++) { lookcgpu = get_devices(i); if (lookcgpu != cgpu && lookcgpu->usbdev == cgusb) { @@ -1339,15 +1344,12 @@ static void release_cgpu(struct cgpu_info *cgpu) } } - which_intinfo = cgpu->usbdev->found->which_intinfo; _usb_uninit(cgpu); - if (which_intinfo == 0) - cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address); + cgminer_usb_unlock_bd(cgpu->drv, cgpu->usbinfo.bus_number, cgpu->usbinfo.device_address); } /* - * Used by MMQ - use the same usbdev thus locking is across all 4 related devices - * since they must use the same USB handle since they use the same interface + * Use the same usbdev thus locking is across all related devices */ struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig) { @@ -1371,80 +1373,11 @@ struct cgpu_info *usb_copy_cgpu(struct cgpu_info *orig) copy->usbinfo.nodev = (copy->usbdev == NULL); - copy->usbinfo.devlock = orig->usbinfo.devlock; - DEVUNLOCK(orig, pstate); return copy; } -/* - * Used by CMR - use a different usbdev - since they must use a different - * USB handle due to using different interfaces (libusb requirement) - * N.B. multiple interfaces don't as yet work in windows libusb - * so the CMR defines above that use them are defined out in windows - * Nothing else uses multiple interfaces as at 20130922 - */ -static struct cgpu_info *usb_dup_cgpu(struct cgpu_info *orig, int intinfo) -{ - struct cgpu_info *copy; - - copy = calloc(1, sizeof(*copy)); - if (unlikely(!copy)) - quit(1, "Failed to calloc cgpu for %s in usb_dup_cgpu", orig->drv->dname); - - copy->name = orig->name; - copy->drv = copy_drv(orig->drv); - copy->deven = orig->deven; - copy->threads = orig->threads; - - if (orig->usbdev) { - copy->usbdev = calloc(1, sizeof(*(copy->usbdev))); - if (unlikely(!copy->usbdev)) - quit(1, "Failed to calloc usbdev for %s in usb_dup_cgpu", orig->drv->dname); - - copy->usbdev->found = malloc(sizeof(*(copy->usbdev->found))); - if (unlikely(!copy->usbdev->found)) - quit(1, "Failed to malloc found for %s in usb_dup_cgpu", orig->drv->dname); - memcpy(copy->usbdev->found, orig->usbdev->found, sizeof(*(copy->usbdev->found))); - - copy->usbdev->found->which_intinfo = intinfo; - - copy->usbdev->descriptor = NULL; // don't need it - copy->usbdev->usb_type = orig->usbdev->usb_type; - copy->usbdev->ident = orig->usbdev->ident; - copy->usbdev->usbver = orig->usbdev->usbver; - copy->usbdev->cps = orig->usbdev->cps; - copy->usbdev->usecps = orig->usbdev->usecps; - if (orig->usbdev->prod_string == BLANK) - copy->usbdev->prod_string = (char *)BLANK; - else - copy->usbdev->prod_string = strdup(orig->usbdev->prod_string); - if (orig->usbdev->manuf_string == BLANK) - copy->usbdev->manuf_string = (char *)BLANK; - else - copy->usbdev->manuf_string = strdup(orig->usbdev->manuf_string); - if (orig->usbdev->serial_string == BLANK) - copy->usbdev->serial_string = (char *)BLANK; - else - copy->usbdev->serial_string = strdup(orig->usbdev->serial_string); - copy->usbdev->fwVersion = orig->usbdev->fwVersion; - copy->usbdev->interfaceVersion = orig->usbdev->interfaceVersion; - } - - memcpy(&(copy->usbinfo), &(orig->usbinfo), sizeof(copy->usbinfo)); - - copy->usbinfo.nodev = (copy->usbdev == NULL); - - copy->usbinfo.devlock = calloc(1, sizeof(*(copy->usbinfo.devlock))); - if (unlikely(!copy->usbinfo.devlock)) - quit(1, "Failed to calloc devlock for %s in usb_dup_cgpu", orig->drv->dname); - - rwlock_init(copy->usbinfo.devlock); - - return copy; -} - struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads) { struct cgpu_info *cgpu = calloc(1, sizeof(*cgpu)); @@ -1497,7 +1430,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u char devstr[STRBUFLEN+1]; int err, ifinfo, epinfo, alt, epnum, pstate; int bad = USB_INIT_FAIL; - int cfg; + int cfg, claimed = 0; DEVLOCK(cgpu, pstate); @@ -1508,7 +1441,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u snprintf(devpath, sizeof(devpath), "%d:%d-i%d", (int)(cgpu->usbinfo.bus_number), (int)(cgpu->usbinfo.device_address), - FOUNDIF(found)); + THISIF(found, 0)); } else { snprintf(devpath, sizeof(devpath), "%d:%d", (int)(cgpu->usbinfo.bus_number), @@ -1570,18 +1503,22 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u } #ifndef WIN32 - if (libusb_kernel_driver_active(cgusb->handle, FOUNDIF(found)) == 1) { - applog(LOG_DEBUG, "USB init, kernel attached ... %s", devstr); - err = libusb_detach_kernel_driver(cgusb->handle, FOUNDIF(found)); - if (err == 0) { - applog(LOG_DEBUG, - "USB init, kernel detached interface %d successfully %s", - FOUNDIF(found), devstr); - } else { - applog(LOG_WARNING, - "USB init, kernel detach interface %d failed, err %d in use? %s", - FOUNDIF(found), err, devstr); - goto cldame; + for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) { + if (libusb_kernel_driver_active(cgusb->handle, THISIF(found, ifinfo)) == 1) { + applog(LOG_DEBUG, "USB init, kernel attached ... %s", devstr); + err = libusb_detach_kernel_driver(cgusb->handle, THISIF(found, ifinfo)); + if (err == 0) { + applog(LOG_DEBUG, + "USB init, kernel detached ifinfo %d interface %d" + " successfully %s", + ifinfo, THISIF(found, ifinfo), devstr); + } else { + applog(LOG_WARNING, + "USB init, kernel detach ifinfo %d interface %d failed," + " err %d in use? %s", + ifinfo, THISIF(found, ifinfo), err, devstr); + goto cldame; + } } } #endif @@ -1704,20 +1641,26 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u goto cldame; } - err = libusb_claim_interface(cgusb->handle, FOUNDIF(found)); - if (err) { - switch(err) { - case LIBUSB_ERROR_BUSY: - applog(LOG_WARNING, - "USB init, claim interface %d in use %s", - FOUNDIF(found), devstr); - break; - default: - applog(LOG_DEBUG, - "USB init, claim interface %d failed, err %d %s", - FOUNDIF(found), err, devstr); + claimed = 0; + for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) { + err = libusb_claim_interface(cgusb->handle, THISIF(found, ifinfo)); + if (err == 0) + claimed++; + else { + switch(err) { + case LIBUSB_ERROR_BUSY: + applog(LOG_WARNING, + "USB init, claim ifinfo %d interface %d in use %s", + ifinfo, THISIF(found, ifinfo), devstr); + break; + default: + applog(LOG_DEBUG, + "USB init, claim ifinfo %d interface %d failed," + " err %d %s", + ifinfo, THISIF(found, ifinfo), err, devstr); + } + goto reldame; } - goto reldame; } cfg = -1; @@ -1784,7 +1727,9 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u reldame: - libusb_release_interface(cgusb->handle, FOUNDIF(found)); + ifinfo = claimed; + while (ifinfo-- > 0) + libusb_release_interface(cgusb->handle, THISIF(found, ifinfo)); cldame: @@ -1806,144 +1751,6 @@ out_unlock: return bad; } -// To get the extra interfaces on a multi interface device -struct cgpu_info *usb_init_intinfo(struct cgpu_info *orig, int intinfo) -{ - struct usb_find_devices *found; - struct libusb_device *dev; - struct cgpu_info *copy = NULL; - char msgstr[STRBUFLEN+1]; - char devstr[STRBUFLEN+1]; - char devpath[32]; - int err, pstate; - - DEVLOCK(orig, pstate); - - snprintf(msgstr, sizeof(msgstr), "USB %s init_intinfo (%d:%d-i%d)", - orig->drv->dname, - (int)(orig->usbinfo.bus_number), - (int)(orig->usbinfo.device_address), - orig->usbdev->found->which_intinfo); - - if (orig->usbinfo.nodev) { - applog(LOG_ERR, "%s cgpu has nodev", msgstr); - goto Hitagi; - } - - if (orig->usbdev->found->which_intinfo != 0) { - applog(LOG_ERR, "%s incorrect cgpu (must be i0)", msgstr); - goto Hitagi; - } - - if (orig->usbdev->found->intinfo_count < 2) { - applog(LOG_ERR, "%s cgpu only has 1 interface", msgstr); - goto Hitagi; - } - - if (intinfo < 1 || intinfo >= orig->usbdev->found->intinfo_count) { - applog(LOG_ERR, "%s invalid intinfo (%d) must be > 0 && < %d", - msgstr, intinfo, orig->usbdev->found->intinfo_count); - goto Hitagi; - } - - dev = libusb_get_device(orig->usbdev->handle); - - copy = usb_dup_cgpu(orig, intinfo); - if (!copy) - goto Hitagi; - - found = copy->usbdev->found; - - snprintf(devpath, sizeof(devpath), "%d:%d-i%d", - (int)(copy->usbinfo.bus_number), - (int)(copy->usbinfo.device_address), - FOUNDIF(found)); - - copy->device_path = strdup(devpath); - - snprintf(devstr, sizeof(devstr), "- %s device %s", found->name, devpath); - - cg_wlock(&cgusb_fd_lock); - err = libusb_open(dev, &(copy->usbdev->handle)); - cg_wunlock(&cgusb_fd_lock); - if (err) { - switch (err) { - case LIBUSB_ERROR_ACCESS: - applog(LOG_ERR, - "USB init_intinfo, open device failed, err %d, " - "you don't have privilege to access %s", - err, devstr); - break; -#ifdef WIN32 - // Windows specific message - case LIBUSB_ERROR_NOT_SUPPORTED: - applog(LOG_ERR, - "USB init_intinfo, open device failed, err %d, " - "you need to install a WinUSB driver for %s", - err, devstr); - break; -#endif - default: - applog(LOG_DEBUG, - "USB init_intinfo, open failed, err %d %s", - err, devstr); - } - goto Hitagi; - } - -#ifndef WIN32 - if (libusb_kernel_driver_active(copy->usbdev->handle, FOUNDIF(found)) == 1) { - applog(LOG_DEBUG, "USB init_intinfo, kernel attached ... %s", devstr); - err = libusb_detach_kernel_driver(copy->usbdev->handle, FOUNDIF(found)); - if (err == 0) { - applog(LOG_DEBUG, - "USB init_intinfo, kernel detached interface %d successfully %s", - FOUNDIF(found), devstr); - } else { - applog(LOG_WARNING, - "USB init_intinfo, kernel detach interface %d failed, err %d in use? %s", - FOUNDIF(found), err, devstr); - goto HitagiClose; - } - } -#endif - - err = libusb_claim_interface(copy->usbdev->handle, FOUNDIF(found)); - if (err) { - switch(err) { - case LIBUSB_ERROR_BUSY: - applog(LOG_WARNING, - "USB init_intinfo, claim interface %d in use %s", - FOUNDIF(found), devstr); - break; - default: - applog(LOG_DEBUG, - "USB init_intinfo, claim interface %d failed, err %d %s", - FOUNDIF(found), err, devstr); - } - goto HitagiClose; - } - - goto Hitagi; - -HitagiClose: - - cg_wlock(&cgusb_fd_lock); - libusb_close(copy->usbdev->handle); - copy->usbdev->handle = NULL; - cg_wunlock(&cgusb_fd_lock); - - copy->usbdev = free_cgusb(copy->usbdev); - - copy = usb_free_cgpu(copy); - -Hitagi: - - DEVUNLOCK(orig, pstate); - - return copy; -} - bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found_match) { struct usb_find_devices *found_use = NULL; @@ -2502,7 +2309,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, return err; } -int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce) +int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce) { struct cg_usb_device *usbdev; bool ftdi; @@ -2530,7 +2337,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int usbdev = cgpu->usbdev; ftdi = (usbdev->usb_type == USB_TYPE_FTDI); - USBDEBUG("USB debug: _usb_read(%s (nodev=%s),epinfo=%d,buf=%p,bufsiz=%zu,proc=%p,timeout=%u,end=%s,cmd=%s,ftdi=%s,readonce=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), epinfo, buf, bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce)); + USBDEBUG("USB debug: _usb_read(%s (nodev=%s),intinfo=%d,epinfo=%d,buf=%p,bufsiz=%zu,proc=%p,timeout=%u,end=%s,cmd=%s,ftdi=%s,readonce=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, buf, bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce)); if (bufsiz > USB_MAX_READ) quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, (int)bufsiz, USB_MAX_READ); @@ -2584,7 +2391,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int } } err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, epinfo), + USBEP(usbdev, intinfo, epinfo), ptr, usbbufread, &got, timeout, cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); @@ -2688,7 +2495,7 @@ int _usb_read(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int } } err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, epinfo), ptr, + USBEP(usbdev, intinfo, epinfo), ptr, usbbufread, &got, timeout, cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); @@ -2775,7 +2582,7 @@ out_unlock: return err; } -int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds cmd) +int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds cmd) { struct cg_usb_device *usbdev; struct timeval read_start, tv_finish; @@ -2786,7 +2593,7 @@ int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int DEVLOCK(cgpu, pstate); - USBDEBUG("USB debug: _usb_write(%s (nodev=%s),epinfo=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), epinfo, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); + USBDEBUG("USB debug: _usb_write(%s (nodev=%s),intinfo=%d,epinfo=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); *processed = 0; @@ -2829,7 +2636,7 @@ int _usb_write(struct cgpu_info *cgpu, int epinfo, char *buf, size_t bufsiz, int usbdev->last_write_siz = bufsiz; } err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, epinfo), + USBEP(usbdev, intinfo, epinfo), (unsigned char *)buf, bufsiz, &sent, timeout, cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); @@ -3046,7 +2853,7 @@ int usb_ftdi_cts(struct cgpu_info *cgpu) return (ret & FTDI_RS0_CTS); } -int usb_ftdi_set_latency(struct cgpu_info *cgpu) +int _usb_ftdi_set_latency(struct cgpu_info *cgpu, int intinfo) { int err = 0; int pstate; @@ -3067,7 +2874,7 @@ int usb_ftdi_set_latency(struct cgpu_info *cgpu) if (!err) err = __usb_transfer(cgpu, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, cgpu->usbdev->found->latency, - USBIF(cgpu->usbdev), + USBIF(cgpu->usbdev, intinfo), NULL, 0, DEVTIMEOUT, C_LATENCY); } @@ -3185,8 +2992,10 @@ void usb_disable_cps(struct cgpu_info *cgpu) * The value returned (0) when usbdev is NULL * doesn't matter since it also means the next call to * any usbutils function will fail with a nodev + * N.B. this is to get the interface number to use in a control_transfer + * which for some devices isn't actually the interface number */ -int usb_interface(struct cgpu_info *cgpu) +int _usb_interface(struct cgpu_info *cgpu, int intinfo) { int interface = 0; int pstate; @@ -3194,7 +3003,7 @@ int usb_interface(struct cgpu_info *cgpu) DEVLOCK(cgpu, pstate); if (cgpu->usbdev) - interface = USBIF(cgpu->usbdev); + interface = cgpu->usbdev->found->intinfos[intinfo].ctrl_transfer; DEVUNLOCK(cgpu, pstate); diff --git a/usbutils.h b/usbutils.h index 779c0570..1ef32711 100644 --- a/usbutils.h +++ b/usbutils.h @@ -109,6 +109,9 @@ // Use the device defined timeout #define DEVTIMEOUT 0 +// The default intinfo structure used is the first one +#define DEFAULT_INTINFO 0 + // For endpoints defined in usb_find_devices.intinfos.epinfos, // the first two must be the default IN and OUT and both must always exist #define DEFAULT_EP_IN 0 @@ -123,6 +126,7 @@ struct usb_epinfo { struct usb_intinfo { int interface; + int ctrl_transfer; int epinfo_count; struct usb_epinfo *epinfos; }; @@ -158,7 +162,6 @@ struct usb_find_devices { unsigned int timeout; uint16_t wMaxPacketSize; uint16_t latency; - int which_intinfo; int intinfo_count; struct usb_intinfo *intinfos; }; @@ -217,6 +220,7 @@ struct cg_usb_tmo { struct cg_usb_info { uint8_t bus_number; uint8_t device_address; + int which_intinfo; int usbstat; bool nodev; int nodev_count; @@ -341,17 +345,17 @@ struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads); struct cgpu_info *usb_free_cgpu_devlock(struct cgpu_info *cgpu, bool free_devlock); #define usb_free_cgpu(cgpu) usb_free_cgpu_devlock(cgpu, true) void usb_uninit(struct cgpu_info *cgpu); -struct cgpu_info *usb_init_intinfo(struct cgpu_info *orig, int intinfo); bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found); void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *)); struct api_data *api_usb_stats(int *count); void update_usb_stats(struct cgpu_info *cgpu); -int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce); -int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds); +int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce); +int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds); int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd); int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, enum usb_cmds cmd); int usb_ftdi_cts(struct cgpu_info *cgpu); -int usb_ftdi_set_latency(struct cgpu_info *cgpu); +int _usb_ftdi_set_latency(struct cgpu_info *cgpu, int intinfo); +#define usb_ftdi_set_latency(_cgpu) _usb_ftdi_set_latency(_cgpu, DEFAULT_INTINFO) void usb_buffer_enable(struct cgpu_info *cgpu); void usb_buffer_disable(struct cgpu_info *cgpu); void usb_buffer_clear(struct cgpu_info *cgpu); @@ -359,7 +363,8 @@ uint32_t usb_buffer_size(struct cgpu_info *cgpu); void usb_set_cps(struct cgpu_info *cgpu, int cps); void usb_enable_cps(struct cgpu_info *cgpu); void usb_disable_cps(struct cgpu_info *cgpu); -int usb_interface(struct cgpu_info *cgpu); +int _usb_interface(struct cgpu_info *cgpu, int intinfo); +#define usb_interface(_cgpu) _usb_interface(_cgpu, DEFAULT_INTINFO) enum sub_ident usb_ident(struct cgpu_info *cgpu); void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize); void usb_set_dev_start(struct cgpu_info *cgpu); @@ -368,46 +373,52 @@ void usb_initialise(); void *usb_resource_thread(void *userdata); #define usb_read(cgpu, buf, bufsiz, read, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) #define usb_read_once(cgpu, buf, bufsiz, read, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) #define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) #define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false) #define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false) #define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false) #define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, false) #define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \ - _usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) #define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ - _usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false) + +#define usb_read_ii_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \ + _usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false) #define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \ - _usb_read(cgpu, ep, buf, bufsiz, read, timeout, NULL, cmd, false) + _usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, timeout, NULL, cmd, false) #define usb_write(cgpu, buf, bufsiz, wrote, cmd) \ - _usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd) + _usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd) + +#define usb_write_ii(cgpu, intinfo, buf, bufsiz, wrote, cmd) \ + _usb_write(cgpu, intinfo, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd) #define usb_write_ep(cgpu, ep, buf, bufsiz, wrote, cmd) \ - _usb_write(cgpu, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd) + _usb_write(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd) #define usb_write_timeout(cgpu, buf, bufsiz, wrote, timeout, cmd) \ - _usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd) + _usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd) #define usb_write_ep_timeout(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) \ - _usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) + _usb_write(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, timeout, cmd) #define usb_transfer(cgpu, typ, req, val, idx, cmd) \ _usb_transfer(cgpu, typ, req, val, idx, NULL, 0, DEVTIMEOUT, cmd) From 39c52b1fb44cf5348b06283f4ae14a9761facd64 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 20:58:47 +1000 Subject: [PATCH 37/88] Use the test_nonce function within submit_nonce and store the uint32 corresponding to hash2 37 for further use. --- cgminer.c | 15 +++------------ miner.h | 1 + 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/cgminer.c b/cgminer.c index 49931b66..5afb3df2 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6021,29 +6021,20 @@ bool test_nonce(struct work *work, uint32_t nonce) flip32(hash2_32, work->hash); diff1targ = opt_scrypt ? 0x0000ffffUL : 0; - return (be32toh(hash2_32[7] <= diff1targ)); + work->hash2_32_7 = be32toh(hash2_32[7]); + return (work->hash2_32_7 <= diff1targ); } /* Returns true if nonce for work was a valid share */ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) { - uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12); struct timeval tv_work_found; unsigned char hash2[32]; - uint32_t *hash2_32 = (uint32_t *)hash2; - uint32_t diff1targ; bool ret = true; cgtime(&tv_work_found); - *work_nonce = htole32(nonce); - work->share_diff = 0; - /* Do one last check before attempting to submit the work */ - rebuild_hash(work); - flip32(hash2_32, work->hash); - - diff1targ = opt_scrypt ? 0x0000ffffUL : 0; - if (be32toh(hash2_32[7]) > diff1targ) { + if (!test_nonce(work, nonce)) { applog(LOG_INFO, "%s%d: invalid nonce - HW error", thr->cgpu->drv->name, thr->cgpu->device_id); diff --git a/miner.h b/miner.h index 14562272..5bb40386 100644 --- a/miner.h +++ b/miner.h @@ -1263,6 +1263,7 @@ struct work { #endif double device_diff; uint64_t share_diff; + uint32_t hash2_32_7; int rolls; From b932fc0adae7a9fed3a795790026f9575a25da1c Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 26 Sep 2013 21:04:28 +1000 Subject: [PATCH 38/88] usbutils - which_intinfo not requried --- usbutils.h | 1 - 1 file changed, 1 deletion(-) diff --git a/usbutils.h b/usbutils.h index 1ef32711..c30b98b9 100644 --- a/usbutils.h +++ b/usbutils.h @@ -220,7 +220,6 @@ struct cg_usb_tmo { struct cg_usb_info { uint8_t bus_number; uint8_t device_address; - int which_intinfo; int usbstat; bool nodev; int nodev_count; From 76e688aee1241a9ab437996adb4c3359224211d7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 21:14:14 +1000 Subject: [PATCH 39/88] Store the hash2 array in struct work for further reuse. --- cgminer.c | 9 +++------ miner.h | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/cgminer.c b/cgminer.c index 5afb3df2..77f973fc 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6010,8 +6010,7 @@ void inc_hw_errors(struct thr_info *thr) bool test_nonce(struct work *work, uint32_t nonce) { uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12); - unsigned char hash2[32]; - uint32_t *hash2_32 = (uint32_t *)hash2; + uint32_t *hash2_32 = (uint32_t *)work->hash2; uint32_t diff1targ; *work_nonce = htole32(nonce); @@ -6021,15 +6020,13 @@ bool test_nonce(struct work *work, uint32_t nonce) flip32(hash2_32, work->hash); diff1targ = opt_scrypt ? 0x0000ffffUL : 0; - work->hash2_32_7 = be32toh(hash2_32[7]); - return (work->hash2_32_7 <= diff1targ); + return (be32toh(hash2_32[7]) <= diff1targ); } /* Returns true if nonce for work was a valid share */ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) { struct timeval tv_work_found; - unsigned char hash2[32]; bool ret = true; cgtime(&tv_work_found); @@ -6052,7 +6049,7 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) thr->cgpu->last_device_valid_work = time(NULL); mutex_unlock(&stats_lock); - if (!fulltest(hash2, work->target)) { + if (!fulltest(work->hash2, work->target)) { applog(LOG_INFO, "Share below target"); goto out; } diff --git a/miner.h b/miner.h index 5bb40386..d8d41484 100644 --- a/miner.h +++ b/miner.h @@ -1263,7 +1263,7 @@ struct work { #endif double device_diff; uint64_t share_diff; - uint32_t hash2_32_7; + unsigned char hash2[32]; int rolls; From 7696f26a93aab382f6983f30e00029fe160b8624 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 21:18:33 +1000 Subject: [PATCH 40/88] Abstract out work submission once it's been tested, to be used by drivers that do their own internal validity testing. --- cgminer.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/cgminer.c b/cgminer.c index 77f973fc..953ab027 100644 --- a/cgminer.c +++ b/cgminer.c @@ -6023,22 +6023,11 @@ bool test_nonce(struct work *work, uint32_t nonce) return (be32toh(hash2_32[7]) <= diff1targ); } -/* Returns true if nonce for work was a valid share */ -bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) +/* To be used once the work has been tested to be meet diff1 and has had its + * nonce adjusted. */ +void submit_tested_work(struct thr_info *thr, struct work *work) { struct timeval tv_work_found; - bool ret = true; - - cgtime(&tv_work_found); - - if (!test_nonce(work, nonce)) { - applog(LOG_INFO, "%s%d: invalid nonce - HW error", - thr->cgpu->drv->name, thr->cgpu->device_id); - - inc_hw_errors(thr); - ret = false; - goto out; - } work->share_diff = share_diff(work); @@ -6051,11 +6040,28 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) if (!fulltest(work->hash2, work->target)) { applog(LOG_INFO, "Share below target"); - goto out; + return; } + cgtime(&tv_work_found); submit_work_async(work, &tv_work_found); -out: +} + +/* Returns true if nonce for work was a valid share */ +bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) +{ + bool ret = true; + + if (test_nonce(work, nonce)) + submit_tested_work(thr, work); + else { + applog(LOG_INFO, "%s%d: invalid nonce - HW error", + thr->cgpu->drv->name, thr->cgpu->device_id); + + inc_hw_errors(thr); + ret = false; + } + return ret; } From b606a60349fe2f1c1c56a1fec833ec849b798676 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Sep 2013 21:20:59 +1000 Subject: [PATCH 41/88] Use submit_tested_work in bitfury driver to avoid unnecessarily re-testing the work for validity. --- driver-bitfury.c | 6 ++---- miner.h | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 44e90e0e..a5ca5630 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -168,13 +168,11 @@ const uint32_t bf_offsets[] = {0, -0x400000, -0x800000}; static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce) { - uint32_t offset_nonce; int i; for (i = 0; i < BT_OFFSETS; i++) { - offset_nonce = nonce + bf_offsets[i]; - if (test_nonce(work, offset_nonce)) { - submit_nonce(thr, work, offset_nonce); + if (test_nonce(work, nonce + bf_offsets[i])) { + submit_tested_work(thr, work); return true; } } diff --git a/miner.h b/miner.h index d8d41484..867ca0e6 100644 --- a/miner.h +++ b/miner.h @@ -1358,6 +1358,7 @@ struct modminer_fpga_state { extern void get_datestamp(char *, size_t, struct timeval *); extern void inc_hw_errors(struct thr_info *thr); extern bool test_nonce(struct work *work, uint32_t nonce); +extern void submit_tested_work(struct thr_info *thr, struct work *work); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern struct work *get_queued(struct cgpu_info *cgpu); extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); From 4f6c7ee0c14d38207fe0cbde137a7eb9187d28c9 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 09:39:26 +1000 Subject: [PATCH 42/88] Name remainder of BFU usb commands used. --- driver-bitfury.c | 4 ++-- usbutils.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 4d666c15..bd2835c1 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -23,7 +23,7 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) int amount; do { - usb_read(bitfury, buf, 512, &amount, C_PING); + usb_read(bitfury, buf, 512, &amount, C_BF1_FLUSH); } while (amount); } @@ -48,7 +48,7 @@ static void bitfury_identify(struct cgpu_info *bitfury) { int amount; - usb_write(bitfury, "L", 1, &amount, C_PING); + usb_write(bitfury, "L", 1, &amount, C_BF1_IDENTIFY); } static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info) diff --git a/usbutils.h b/usbutils.h index 7c458d84..c4aaed81 100644 --- a/usbutils.h +++ b/usbutils.h @@ -333,7 +333,9 @@ struct cg_usb_info { USB_ADD_COMMAND(C_BF1_GETRESET, "BF1GetReset") \ USB_ADD_COMMAND(C_BF1_REQWORK, "BF1RequestWork") \ USB_ADD_COMMAND(C_BF1_GETWORK, "BF1GetWork") \ - USB_ADD_COMMAND(C_BF1_GETRES, "BF1GetResults") + USB_ADD_COMMAND(C_BF1_GETRES, "BF1GetResults") \ + USB_ADD_COMMAND(C_BF1_FLUSH, "BF1Flush") \ + USB_ADD_COMMAND(C_BF1_IDENTIFY, "BF1Identify") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ #define USB_ADD_COMMAND(X, Y) X, From 1a0202812a196a3e9efb61d2e73f37f7d44d8baa Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 09:41:55 +1000 Subject: [PATCH 43/88] Add more read_ii variants to usbutils. --- usbutils.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/usbutils.h b/usbutils.h index c4aaed81..d8bb6489 100644 --- a/usbutils.h +++ b/usbutils.h @@ -386,12 +386,18 @@ void *usb_resource_thread(void *userdata); #define usb_read(cgpu, buf, bufsiz, read, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) +#define usb_read_ii(cgpu, intinfo, buf, bufsiz, read, cmd) \ + _usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false) + #define usb_read_once(cgpu, buf, bufsiz, read, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) #define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) +#define usb_read_ii_once_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \ + _usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) + #define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false) From a62267fa9325afb134cf15fa868038004917998e Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 09:44:58 +1000 Subject: [PATCH 44/88] usbutils - add USBDEBUG for usb_bulk_transfer --- usbutils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usbutils.c b/usbutils.c index 2cd902fe..3f8fc40c 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2253,6 +2253,8 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, if (endpoint == LIBUSB_ENDPOINT_OUT) memcpy(buf, data, length); + USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),endpoint=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), (int)endpoint, data, length, timeout, mode, usb_cmdname(cmd), seq); + STATS_TIMEVAL(&tv_start); cg_rlock(&cgusb_fd_lock); err = libusb_bulk_transfer(dev_handle, endpoint, data, length, From d8518f43367d9e0654d59472322893b84e35f380 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 10:08:59 +1000 Subject: [PATCH 45/88] usbutils - bulk transfer copy test fix --- usbutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usbutils.c b/usbutils.c index 3f8fc40c..0d2b221e 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2250,7 +2250,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, if (length > MaxPacketSize) length = MaxPacketSize; buf = alloca(MaxPacketSize); - if (endpoint == LIBUSB_ENDPOINT_OUT) + if ((endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) memcpy(buf, data, length); USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),endpoint=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), (int)endpoint, data, length, timeout, mode, usb_cmdname(cmd), seq); From 7deaa91b2684a30c63ad955f303fc518483e2ea4 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 10:36:23 +1000 Subject: [PATCH 46/88] Add information for 2nd USB interface on BF1 devices and choose interface 1 for bulk transfers. --- driver-bitfury.c | 22 +++++++++++----------- driver-bitfury.h | 1 + usbutils.c | 9 +++++++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index bd2835c1..5952501d 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -23,7 +23,7 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) int amount; do { - usb_read(bitfury, buf, 512, &amount, C_BF1_FLUSH); + usb_read_ii(bitfury, 1, buf, 512, &amount, C_BF1_FLUSH); } while (amount); } @@ -48,7 +48,7 @@ static void bitfury_identify(struct cgpu_info *bitfury) { int amount; - usb_write(bitfury, "L", 1, &amount, C_BF1_IDENTIFY); + usb_write_ii(bitfury, 1, "L", 1, &amount, C_BF1_IDENTIFY); } static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info) @@ -56,8 +56,8 @@ static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info char buf[512]; int amount; - usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); - usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); + usb_write_ii(bitfury, 1, "I", 1, &amount, C_BF1_REQINFO); + usb_read_ii(bitfury, 1, buf, 14, &amount, C_BF1_GETINFO); if (amount != 14) { applog(LOG_INFO, "%s %d: Getinfo received %d bytes", bitfury->drv->name, bitfury->device_id, amount); @@ -78,8 +78,8 @@ static bool bitfury_reset(struct cgpu_info *bitfury) char buf[512]; int amount; - usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET); - usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); + usb_write_ii(bitfury, 1, "R", 1, &amount, C_BF1_REQRESET); + usb_read_ii_timeout(bitfury, 1, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); if (amount != 7) { applog(LOG_INFO, "%s %d: Getreset received %d bytes", @@ -202,7 +202,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, cgtime(&tv_now); ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start); if (ms_diff > 0) { - usb_read_timeout(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES); + usb_read_ii_timeout(bitfury, 1, info->buf, 512, &amount, ms_diff, C_BF1_GETRES); info->tot += amount; } @@ -215,10 +215,10 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start); if (unlikely(ms_diff < 10)) ms_diff = 10; - usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); + usb_read_ii_once_timeout(bitfury, 1, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); info->tot += amount; while (amount) { - usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); + usb_read_ii_once_timeout(bitfury, 1, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); info->tot += amount; }; @@ -226,10 +226,10 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, goto cascade; /* Send work */ - usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK); + usb_write_ii(bitfury, 1, buf, 45, &amount, C_BF1_REQWORK); cgtime(&info->tv_start); /* Get response acknowledging work */ - usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); + usb_read_ii(bitfury, 1, buf, 7, &amount, C_BF1_GETWORK); /* Only happens on startup */ if (unlikely(!info->prevwork[BF1ARRAY_SIZE])) diff --git a/driver-bitfury.h b/driver-bitfury.h index db133231..9cbe4200 100644 --- a/driver-bitfury.h +++ b/driver-bitfury.h @@ -16,6 +16,7 @@ #define BF1ARRAY_SIZE 2 struct bitfury_info { + struct cgpu_info *base_cgpu; uint8_t version; char product[8]; uint32_t serial; diff --git a/usbutils.c b/usbutils.c index a79e556f..ee36404d 100644 --- a/usbutils.c +++ b/usbutils.c @@ -131,13 +131,18 @@ static struct usb_intinfo bfl_ints[] = { #endif #ifdef USE_BITFURY -static struct usb_epinfo bfu_epinfos[] = { +static struct usb_epinfo bfu0_epinfos[] = { + { LIBUSB_TRANSFER_TYPE_INTERRUPT, 8, EPI(2), 0 } +}; + +static struct usb_epinfo bfu1_epinfos[] = { { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0 }, { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0 } }; static struct usb_intinfo bfu_ints[] = { - USB_EPS(1, bfu_epinfos) + USB_EPS(0, bfu0_epinfos), + USB_EPS(1, bfu1_epinfos) }; #endif From 1f74b2cdc4d630d678f12d55b2153145e699c97a Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 10:50:33 +1000 Subject: [PATCH 47/88] Perform interrupt read flush as per serial open on BF1 devices. --- driver-bitfury.c | 4 ++++ usbutils.h | 1 + 2 files changed, 5 insertions(+) diff --git a/driver-bitfury.c b/driver-bitfury.c index 5952501d..5cd83a27 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -29,6 +29,10 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) static void bitfury_open(struct cgpu_info *bitfury) { + char buf[8]; + int amount; + + usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); /* Magic open sequence */ usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); bitfury_empty_buffer(bitfury); diff --git a/usbutils.h b/usbutils.h index d8bb6489..5566d142 100644 --- a/usbutils.h +++ b/usbutils.h @@ -335,6 +335,7 @@ struct cg_usb_info { USB_ADD_COMMAND(C_BF1_GETWORK, "BF1GetWork") \ USB_ADD_COMMAND(C_BF1_GETRES, "BF1GetResults") \ USB_ADD_COMMAND(C_BF1_FLUSH, "BF1Flush") \ + USB_ADD_COMMAND(C_BF1_IFLUSH, "BF1InterruptFlush") \ USB_ADD_COMMAND(C_BF1_IDENTIFY, "BF1Identify") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ From 93d4c09c66061e504d237e3a350b4962400fc2ed Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 10:54:24 +1000 Subject: [PATCH 48/88] Perform interrupt read after close message on BF1 as per serial close. --- driver-bitfury.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/driver-bitfury.c b/driver-bitfury.c index 5cd83a27..18a57b63 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -40,9 +40,13 @@ static void bitfury_open(struct cgpu_info *bitfury) static void bitfury_close(struct cgpu_info *bitfury) { + char buf[8]; + int amount; + bitfury_empty_buffer(bitfury); /* Magic close sequence */ usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_CLOSE); + usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); bitfury_empty_buffer(bitfury); usb_transfer(bitfury, 0x23, 0x08, 0x9053, 1, C_BF1_CLOSE); bitfury_empty_buffer(bitfury); From 59b33c1a58f4fb27588d98cb1e15f5e5468c1fce Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 11:13:38 +1000 Subject: [PATCH 49/88] Abstract out flushing of interrupt reads in BF1 devices. --- driver-bitfury.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 18a57b63..23a0274d 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -27,12 +27,17 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) } while (amount); } -static void bitfury_open(struct cgpu_info *bitfury) +static void bitfury_empty_intbuf(struct cgpu_info *bitfury) { char buf[8]; int amount; usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); +} + +static void bitfury_open(struct cgpu_info *bitfury) +{ + bitfury_empty_intbuf(bitfury); /* Magic open sequence */ usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); bitfury_empty_buffer(bitfury); @@ -40,13 +45,10 @@ static void bitfury_open(struct cgpu_info *bitfury) static void bitfury_close(struct cgpu_info *bitfury) { - char buf[8]; - int amount; - bitfury_empty_buffer(bitfury); /* Magic close sequence */ usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_CLOSE); - usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); + bitfury_empty_intbuf(bitfury); bitfury_empty_buffer(bitfury); usb_transfer(bitfury, 0x23, 0x08, 0x9053, 1, C_BF1_CLOSE); bitfury_empty_buffer(bitfury); From 703724a3f455a5793934a842579c7645d71d69ac Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 11:20:03 +1000 Subject: [PATCH 50/88] Check return code for bitfury_open and release resources properly on failed initialisation. --- driver-bitfury.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 23a0274d..4026bb87 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -35,12 +35,16 @@ static void bitfury_empty_intbuf(struct cgpu_info *bitfury) usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); } -static void bitfury_open(struct cgpu_info *bitfury) +static bool bitfury_open(struct cgpu_info *bitfury) { + int err; + bitfury_empty_intbuf(bitfury); /* Magic open sequence */ - usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); - bitfury_empty_buffer(bitfury); + err = usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); + if (!err) + bitfury_empty_buffer(bitfury); + return !err; } static void bitfury_close(struct cgpu_info *bitfury) @@ -109,10 +113,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device bitfury = usb_alloc_cgpu(&bitfury_drv, 1); - if (!usb_init(bitfury, dev, found)) { - bitfury = usb_free_cgpu(bitfury); + if (!usb_init(bitfury, dev, found)) goto out; - } applog(LOG_INFO, "%s %d: Found at %s", bitfury->drv->name, bitfury->device_id, bitfury->device_path); @@ -123,7 +125,11 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device usb_buffer_enable(bitfury); - bitfury_open(bitfury); + if (!bitfury_open(bitfury)) { + applog(LOG_INFO, "%s %d: Failed to open", bitfury->drv->name, + bitfury->device_id); + goto out_close; + } /* Send getinfo request */ if (!bitfury_getinfo(bitfury, info)) @@ -145,7 +151,9 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device return true; out_close: bitfury_close(bitfury); + usb_uninit(bitfury); out: + bitfury = usb_free_cgpu(bitfury); return false; } From b994a4c64d091fe4c38b3deabc0f7e2375e532a3 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 11:25:13 +1000 Subject: [PATCH 51/88] Check return codes in getinfo and reset and fail as needed in BF1. --- driver-bitfury.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 4026bb87..32f22f69 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -67,13 +67,23 @@ static void bitfury_identify(struct cgpu_info *bitfury) static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info) { - char buf[512]; - int amount; + int amount, err; + char buf[16]; - usb_write_ii(bitfury, 1, "I", 1, &amount, C_BF1_REQINFO); - usb_read_ii(bitfury, 1, buf, 14, &amount, C_BF1_GETINFO); + err = usb_write_ii(bitfury, 1, "I", 1, &amount, C_BF1_REQINFO); + if (err) { + applog(LOG_INFO, "%s %d: Failed to write REQINFO", + bitfury->drv->name, bitfury->device_id); + return false; + } + err = usb_read_ii(bitfury, 1, buf, 14, &amount, C_BF1_GETINFO); + if (err) { + applog(LOG_INFO, "%s %d: Failed to read GETINFO", + bitfury->drv->name, bitfury->device_id); + return false; + } if (amount != 14) { - applog(LOG_INFO, "%s %d: Getinfo received %d bytes", + applog(LOG_INFO, "%s %d: Getinfo received %d bytes instead of 14", bitfury->drv->name, bitfury->device_id, amount); return false; } @@ -89,18 +99,27 @@ static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info static bool bitfury_reset(struct cgpu_info *bitfury) { - char buf[512]; - int amount; - - usb_write_ii(bitfury, 1, "R", 1, &amount, C_BF1_REQRESET); - usb_read_ii_timeout(bitfury, 1, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); + int amount, err; + char buf[16]; + err = usb_write_ii(bitfury, 1, "R", 1, &amount, C_BF1_REQRESET); + if (err) { + applog(LOG_INFO, "%s %d: Failed to write REQRESET", + bitfury->drv->name, bitfury->device_id); + return false; + } + err = usb_read_ii_timeout(bitfury, 1, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); + if (err) { + applog(LOG_INFO, "%s %d: Failed to read GETRESET", + bitfury->drv->name, bitfury->device_id); + return false; + } if (amount != 7) { - applog(LOG_INFO, "%s %d: Getreset received %d bytes", + applog(LOG_INFO, "%s %d: Getreset received %d bytes instead of 7", bitfury->drv->name, bitfury->device_id, amount); return false; } - applog(LOG_INFO, "%s %d: Getreset returned %s", bitfury->drv->name, + applog(LOG_DEBUG, "%s %d: Getreset returned %s", bitfury->drv->name, bitfury->device_id, buf); bitfury_empty_buffer(bitfury); return true; From ce16bd2ba41d389e877b2953b5812f5a5dc99696 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 12:38:02 +1000 Subject: [PATCH 52/88] Remove magic control sequences on open/close on BF1 and just flush the read buffers. --- driver-bitfury.c | 28 ++++++++-------------------- usbutils.h | 3 +++ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 32f22f69..f3686166 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -23,39 +23,31 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) int amount; do { - usb_read_ii(bitfury, 1, buf, 512, &amount, C_BF1_FLUSH); + usb_read_ii_once(bitfury, 1, buf, 512, &amount, C_BF1_FLUSH); } while (amount); } static void bitfury_empty_intbuf(struct cgpu_info *bitfury) { - char buf[8]; + char buf[512]; int amount; - usb_read_ii(bitfury, 0, buf, 8, &amount, C_BF1_IFLUSH); + do { + usb_read_ii_once(bitfury, 0, buf, 512, &amount, C_BF1_IFLUSH); + } while (amount); } -static bool bitfury_open(struct cgpu_info *bitfury) +static void bitfury_open(struct cgpu_info *bitfury) { - int err; - bitfury_empty_intbuf(bitfury); - /* Magic open sequence */ - err = usb_transfer(bitfury, 0x21, 0x22, 0x0003, 0, C_BF1_OPEN); - if (!err) - bitfury_empty_buffer(bitfury); - return !err; + bitfury_empty_buffer(bitfury); } static void bitfury_close(struct cgpu_info *bitfury) { bitfury_empty_buffer(bitfury); - /* Magic close sequence */ - usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_CLOSE); bitfury_empty_intbuf(bitfury); bitfury_empty_buffer(bitfury); - usb_transfer(bitfury, 0x23, 0x08, 0x9053, 1, C_BF1_CLOSE); - bitfury_empty_buffer(bitfury); } static void bitfury_identify(struct cgpu_info *bitfury) @@ -144,11 +136,7 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device usb_buffer_enable(bitfury); - if (!bitfury_open(bitfury)) { - applog(LOG_INFO, "%s %d: Failed to open", bitfury->drv->name, - bitfury->device_id); - goto out_close; - } + bitfury_open(bitfury); /* Send getinfo request */ if (!bitfury_getinfo(bitfury, info)) diff --git a/usbutils.h b/usbutils.h index 5566d142..42088c0e 100644 --- a/usbutils.h +++ b/usbutils.h @@ -393,6 +393,9 @@ void *usb_resource_thread(void *userdata); #define usb_read_once(cgpu, buf, bufsiz, read, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) +#define usb_read_ii_once(cgpu, intinfo, buf, bufsiz, read, cmd) \ + _usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true) + #define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \ _usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true) From d3a3b3a73d5f9c69da115e21f73603f105901aed Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 13:07:04 +1000 Subject: [PATCH 53/88] usbutils allow PrefPacketSize per endpoint --- driver-avalon.c | 2 +- usbutils.c | 113 +++++++++++++++++++++++++++++------------------- usbutils.h | 7 +-- 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/driver-avalon.c b/driver-avalon.c index 2873bbc9..333add99 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -720,7 +720,7 @@ static bool avalon_detect_one(libusb_device *dev, struct usb_find_devices *found /* Even though this is an FTDI type chip, we want to do the parsing * all ourselves so set it to std usb type */ avalon->usbdev->usb_type = USB_TYPE_STD; - avalon->usbdev->PrefPacketSize = AVALON_USB_PACKETSIZE; + usb_set_pps(avalon, AVALON_USB_PACKETSIZE); /* We have a real Avalon! */ avalon_initialise(avalon); diff --git a/usbutils.c b/usbutils.c index 0d2b221e..b5db0788 100644 --- a/usbutils.c +++ b/usbutils.c @@ -103,8 +103,8 @@ #ifdef USE_BFLSC // N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 static struct usb_epinfo bas_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo bas_ints[] = { @@ -115,8 +115,8 @@ static struct usb_intinfo bas_ints[] = { #ifdef USE_BITFORCE // N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 static struct usb_epinfo bfl_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo bfl_ints[] = { @@ -126,8 +126,8 @@ static struct usb_intinfo bfl_ints[] = { #ifdef USE_MODMINER static struct usb_epinfo mmq_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(3), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(3), 0, 0, 0 } }; static struct usb_intinfo mmq_ints[] = { @@ -137,8 +137,8 @@ static struct usb_intinfo mmq_ints[] = { #ifdef USE_AVALON static struct usb_epinfo ava_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo ava_ints[] = { @@ -148,8 +148,8 @@ static struct usb_intinfo ava_ints[] = { #ifdef USE_ICARUS static struct usb_epinfo ica_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo ica_ints[] = { @@ -157,8 +157,8 @@ static struct usb_intinfo ica_ints[] = { }; static struct usb_epinfo amu_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(1), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(1), 0, 0, 0 } }; static struct usb_intinfo amu_ints[] = { @@ -166,8 +166,8 @@ static struct usb_intinfo amu_ints[] = { }; static struct usb_epinfo llt_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo llt_ints[] = { @@ -175,8 +175,8 @@ static struct usb_intinfo llt_ints[] = { }; static struct usb_epinfo cmr1_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_intinfo cmr1_ints[] = { @@ -184,20 +184,20 @@ static struct usb_intinfo cmr1_ints[] = { }; static struct usb_epinfo cmr2_epinfos0[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0, 0, 0 } }; static struct usb_epinfo cmr2_epinfos1[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(4), 0, 0, 0 }, }; static struct usb_epinfo cmr2_epinfos2[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(5), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(6), 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(5), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(6), 0, 0, 0 }, }; static struct usb_epinfo cmr2_epinfos3[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(7), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(8), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(7), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(8), 0, 0, 0 } }; static struct usb_intinfo cmr2_ints[] = { @@ -365,7 +365,7 @@ static struct usb_find_devices find_dev[] = { .intinfo_count = 0, .intinfos = NULL }, #endif - { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, NULL } + { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, NULL } }; #ifdef USE_BFLSC @@ -1623,8 +1623,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u && epdesc->wMaxPacketSize >= epinfos[epinfo].size && epdesc->bEndpointAddress == epinfos[epinfo].ep) { epinfos[epinfo].found = true; - // TODO: it's an ep (not device) attribute - found->wMaxPacketSize = epdesc->wMaxPacketSize; + epinfos[epinfo].wMaxPacketSize = epdesc->wMaxPacketSize; break; } } @@ -2228,12 +2227,14 @@ static char *find_end(unsigned char *buf, unsigned char *ptr, int ptrlen, int to #define USB_RETRY_MAX 5 static int -usb_bulk_transfer(struct libusb_device_handle *dev_handle, - unsigned char endpoint, unsigned char *data, int length, +usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo, + int epinfo, unsigned char *data, int length, int *transferred, unsigned int timeout, struct cgpu_info *cgpu, __maybe_unused int mode, enum usb_cmds cmd, __maybe_unused int seq) { + struct usb_epinfo *usb_epinfo; + unsigned char endpoint; uint16_t MaxPacketSize; int err, errn, tries = 0; #if DO_USB_STATS @@ -2241,19 +2242,22 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, #endif unsigned char *buf; + usb_epinfo = &(cgpu->usbdev->found->intinfos[intinfo].epinfos[epinfo]); + endpoint = usb_epinfo->ep; + /* Limit length of transfer to the largest this descriptor supports * and leave the higher level functions to transfer more if needed. */ - if (cgpu->usbdev->PrefPacketSize) - MaxPacketSize = cgpu->usbdev->PrefPacketSize; + if (usb_epinfo->PrefPacketSize) + MaxPacketSize = usb_epinfo->PrefPacketSize; else - MaxPacketSize = cgpu->usbdev->found->wMaxPacketSize; + MaxPacketSize = usb_epinfo->wMaxPacketSize; if (length > MaxPacketSize) length = MaxPacketSize; buf = alloca(MaxPacketSize); if ((endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) memcpy(buf, data, length); - USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),endpoint=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), (int)endpoint, data, length, timeout, mode, usb_cmdname(cmd), seq); + USBDEBUG("USB debug: @usb_bulk_transfer(%s (nodev=%s),intinfo=%d,epinfo=%d,data=%p,length=%d,timeout=%u,mode=%d,cmd=%s,seq=%d) endpoint=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, data, length, timeout, mode, usb_cmdname(cmd), seq, (int)endpoint); STATS_TIMEVAL(&tv_start); cg_rlock(&cgusb_fd_lock); @@ -2392,8 +2396,7 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t cgpu->usbinfo.total_read_delay += sleep_estimate; } } - err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, intinfo, epinfo), + err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo, ptr, usbbufread, &got, timeout, cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); @@ -2496,9 +2499,8 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t cgpu->usbinfo.total_read_delay += sleep_estimate; } } - err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, intinfo, epinfo), ptr, - usbbufread, &got, timeout, + err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo, + ptr, usbbufread, &got, timeout, cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); ptr[got] = '\0'; @@ -2637,10 +2639,9 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_ cgsleep_prepare_r(&usbdev->cgt_last_write); usbdev->last_write_siz = bufsiz; } - err = usb_bulk_transfer(usbdev->handle, - USBEP(usbdev, intinfo, epinfo), - (unsigned char *)buf, bufsiz, &sent, - timeout, cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1); + err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo, + (unsigned char *)buf, bufsiz, &sent, timeout, + cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1); cgtime(&tv_finish); USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent); @@ -3027,14 +3028,36 @@ enum sub_ident usb_ident(struct cgpu_info *cgpu) return ident; } -void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize) +/* + * If you pass both intinfo and epinfo as <0 then it will set all + * endpoints to PrefPacketSize + * If intinfo >=0 but epinfo <0 then it will set all endpoints + * for the given one intinfo to PrefPacketSize + * If both are >=0 then it will set only the specified single + * endpoint (intinfo,epinfo) to PrefPacketSize + */ +void _usb_set_pps(struct cgpu_info *cgpu, int intinfo, int epinfo, uint16_t PrefPacketSize) { + struct usb_find_devices *found; int pstate; DEVLOCK(cgpu, pstate); - if (cgpu->usbdev) - cgpu->usbdev->PrefPacketSize = PrefPacketSize; + if (cgpu->usbdev) { + found = cgpu->usbdev->found; + if (intinfo >= 0 && epinfo >= 0) + found->intinfos[intinfo].epinfos[epinfo].PrefPacketSize = PrefPacketSize; + else { + if (intinfo >= 0) { + for (epinfo = 0; epinfo < found->intinfos[intinfo].epinfo_count; epinfo++) + found->intinfos[intinfo].epinfos[epinfo].PrefPacketSize = PrefPacketSize; + } else { + for (intinfo = 0; intinfo < found->intinfo_count ; intinfo++) + for (epinfo = 0; epinfo < found->intinfos[intinfo].epinfo_count; epinfo++) + found->intinfos[intinfo].epinfos[epinfo].PrefPacketSize = PrefPacketSize; + } + } + } DEVUNLOCK(cgpu, pstate); } diff --git a/usbutils.h b/usbutils.h index c30b98b9..8b0f3761 100644 --- a/usbutils.h +++ b/usbutils.h @@ -121,6 +121,8 @@ struct usb_epinfo { uint8_t att; uint16_t size; unsigned char ep; + uint16_t wMaxPacketSize; + uint16_t PrefPacketSize; bool found; }; @@ -160,7 +162,6 @@ struct usb_find_devices { char *iProduct; int config; unsigned int timeout; - uint16_t wMaxPacketSize; uint16_t latency; int intinfo_count; struct usb_intinfo *intinfos; @@ -195,7 +196,6 @@ struct cg_usb_device { char *buffer; uint32_t bufsiz; uint32_t bufamt; - uint16_t PrefPacketSize; cgtimer_t cgt_last_write; size_t last_write_siz; }; @@ -365,7 +365,8 @@ void usb_disable_cps(struct cgpu_info *cgpu); int _usb_interface(struct cgpu_info *cgpu, int intinfo); #define usb_interface(_cgpu) _usb_interface(_cgpu, DEFAULT_INTINFO) enum sub_ident usb_ident(struct cgpu_info *cgpu); -void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize); +void _usb_set_pps(struct cgpu_info *cgpu, int intinfo, int epinfo, uint16_t PrefPacketSize); +#define usb_set_pps(_cgpu, _pps) _usb_set_pps(_cgpu, -1, -1, _pps) void usb_set_dev_start(struct cgpu_info *cgpu); void usb_cleanup(); void usb_initialise(); From 2fc5c1d0ec6c05870913520158c2a5aaa2928175 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 13:47:35 +1000 Subject: [PATCH 54/88] Set preferred packet sizes per interface on BF1. --- usbutils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usbutils.c b/usbutils.c index f5041849..15896150 100644 --- a/usbutils.c +++ b/usbutils.c @@ -132,12 +132,12 @@ static struct usb_intinfo bfl_ints[] = { #ifdef USE_BITFURY static struct usb_epinfo bfu0_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_INTERRUPT, 8, EPI(2), 0 } + { LIBUSB_TRANSFER_TYPE_INTERRUPT, 8, EPI(2), 0, 8, 0 } }; static struct usb_epinfo bfu1_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0, 16, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0, 16, 0 } }; static struct usb_intinfo bfu_ints[] = { From ffea432f7316f14bf6c75ab2e3f0762d2eb6cbf6 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 14:25:57 +1000 Subject: [PATCH 55/88] usb_bulk_transfer - use the allocated buffer --- usbutils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usbutils.c b/usbutils.c index b5db0788..ba2c9d33 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2261,7 +2261,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo, STATS_TIMEVAL(&tv_start); cg_rlock(&cgusb_fd_lock); - err = libusb_bulk_transfer(dev_handle, endpoint, data, length, + err = libusb_bulk_transfer(dev_handle, endpoint, buf, length, transferred, timeout); errn = errno; cg_runlock(&cgusb_fd_lock); @@ -2309,7 +2309,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo, if (err) cgpu->usbinfo.clear_fail_count++; } - if (endpoint == LIBUSB_ENDPOINT_OUT) + if ((endpoint & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) memcpy(data, buf, length); return err; From 61c2ac571429ff5d6ef4ed42803af58df74373e0 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 14:57:22 +1000 Subject: [PATCH 56/88] usbutils - usb_bulk_transfer fix the buf/data fix --- usbutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usbutils.c b/usbutils.c index ba2c9d33..2b3390bd 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2288,7 +2288,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo, STATS_TIMEVAL(&tv_start); cg_rlock(&cgusb_fd_lock); - err = libusb_bulk_transfer(dev_handle, endpoint, data, + err = libusb_bulk_transfer(dev_handle, endpoint, buf, length, transferred, timeout); errn = errno; cg_runlock(&cgusb_fd_lock); From 8d133706c9bf11711468bffe3ddf0a9242af1ddc Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 15:04:07 +1000 Subject: [PATCH 57/88] Remove unnecessary steps in communicating with BF1 and just use USB interface 1. --- driver-bitfury.c | 35 +++++++++++------------------------ usbutils.c | 5 +++-- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index f3686166..71524437 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -23,38 +23,25 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) int amount; do { - usb_read_ii_once(bitfury, 1, buf, 512, &amount, C_BF1_FLUSH); - } while (amount); -} - -static void bitfury_empty_intbuf(struct cgpu_info *bitfury) -{ - char buf[512]; - int amount; - - do { - usb_read_ii_once(bitfury, 0, buf, 512, &amount, C_BF1_IFLUSH); + usb_read_once(bitfury, buf, 512, &amount, C_BF1_FLUSH); } while (amount); } static void bitfury_open(struct cgpu_info *bitfury) { - bitfury_empty_intbuf(bitfury); bitfury_empty_buffer(bitfury); } static void bitfury_close(struct cgpu_info *bitfury) { bitfury_empty_buffer(bitfury); - bitfury_empty_intbuf(bitfury); - bitfury_empty_buffer(bitfury); } static void bitfury_identify(struct cgpu_info *bitfury) { int amount; - usb_write_ii(bitfury, 1, "L", 1, &amount, C_BF1_IDENTIFY); + usb_write(bitfury, "L", 1, &amount, C_BF1_IDENTIFY); } static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info) @@ -62,13 +49,13 @@ static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info int amount, err; char buf[16]; - err = usb_write_ii(bitfury, 1, "I", 1, &amount, C_BF1_REQINFO); + err = usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO); if (err) { applog(LOG_INFO, "%s %d: Failed to write REQINFO", bitfury->drv->name, bitfury->device_id); return false; } - err = usb_read_ii(bitfury, 1, buf, 14, &amount, C_BF1_GETINFO); + err = usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO); if (err) { applog(LOG_INFO, "%s %d: Failed to read GETINFO", bitfury->drv->name, bitfury->device_id); @@ -94,13 +81,13 @@ static bool bitfury_reset(struct cgpu_info *bitfury) int amount, err; char buf[16]; - err = usb_write_ii(bitfury, 1, "R", 1, &amount, C_BF1_REQRESET); + err = usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET); if (err) { applog(LOG_INFO, "%s %d: Failed to write REQRESET", bitfury->drv->name, bitfury->device_id); return false; } - err = usb_read_ii_timeout(bitfury, 1, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); + err = usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); if (err) { applog(LOG_INFO, "%s %d: Failed to read GETRESET", bitfury->drv->name, bitfury->device_id); @@ -227,7 +214,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, cgtime(&tv_now); ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start); if (ms_diff > 0) { - usb_read_ii_timeout(bitfury, 1, info->buf, 512, &amount, ms_diff, C_BF1_GETRES); + usb_read_timeout(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES); info->tot += amount; } @@ -240,10 +227,10 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start); if (unlikely(ms_diff < 10)) ms_diff = 10; - usb_read_ii_once_timeout(bitfury, 1, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); + usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); info->tot += amount; while (amount) { - usb_read_ii_once_timeout(bitfury, 1, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); + usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); info->tot += amount; }; @@ -251,10 +238,10 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, goto cascade; /* Send work */ - usb_write_ii(bitfury, 1, buf, 45, &amount, C_BF1_REQWORK); + usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK); cgtime(&info->tv_start); /* Get response acknowledging work */ - usb_read_ii(bitfury, 1, buf, 7, &amount, C_BF1_GETWORK); + usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); /* Only happens on startup */ if (unlikely(!info->prevwork[BF1ARRAY_SIZE])) diff --git a/usbutils.c b/usbutils.c index 3b324821..4bd71179 100644 --- a/usbutils.c +++ b/usbutils.c @@ -140,9 +140,10 @@ static struct usb_epinfo bfu1_epinfos[] = { { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0, 16, 0 } }; +/* Default to interface 1 */ static struct usb_intinfo bfu_ints[] = { - USB_EPS(0, bfu0_epinfos), - USB_EPS(1, bfu1_epinfos) + USB_EPS(1, bfu1_epinfos), + USB_EPS(0, bfu0_epinfos) }; #endif From 9b9dde1667cf37b6462a575ad3d57e3ff5b0c568 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 16:56:25 +1000 Subject: [PATCH 58/88] usbutils - fix USBDEBUG warnings --- usbutils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usbutils.c b/usbutils.c index 2b3390bd..b0a4e95f 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2343,7 +2343,7 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t usbdev = cgpu->usbdev; ftdi = (usbdev->usb_type == USB_TYPE_FTDI); - USBDEBUG("USB debug: _usb_read(%s (nodev=%s),intinfo=%d,epinfo=%d,buf=%p,bufsiz=%zu,proc=%p,timeout=%u,end=%s,cmd=%s,ftdi=%s,readonce=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, buf, bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce)); + USBDEBUG("USB debug: _usb_read(%s (nodev=%s),intinfo=%d,epinfo=%d,buf=%p,bufsiz=%d,proc=%p,timeout=%u,end=%s,cmd=%s,ftdi=%s,readonce=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, buf, (int)bufsiz, processed, timeout, end ? (char *)str_text((char *)end) : "NULL", usb_cmdname(cmd), bool_str(ftdi), bool_str(readonce)); if (bufsiz > USB_MAX_READ) quit(1, "%s USB read request %d too large (max=%d)", cgpu->drv->name, (int)bufsiz, USB_MAX_READ); @@ -2402,7 +2402,7 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t cgtime(&tv_finish); ptr[got] = '\0'; - USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); + USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), (int)usbbufread); IOERR_CHECK(cgpu, err); @@ -2505,7 +2505,7 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t cgtime(&tv_finish); ptr[got] = '\0'; - USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); + USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), (int)usbbufread); IOERR_CHECK(cgpu, err); @@ -2597,7 +2597,7 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_ DEVLOCK(cgpu, pstate); - USBDEBUG("USB debug: _usb_write(%s (nodev=%s),intinfo=%d,epinfo=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); + USBDEBUG("USB debug: _usb_write(%s (nodev=%s),intinfo=%d,epinfo=%d,buf='%s',bufsiz=%d,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), intinfo, epinfo, (char *)str_text(buf), (int)bufsiz, processed, timeout, usb_cmdname(cmd)); *processed = 0; From f9476743c2c4d30490f8bfb56eb16c8b4c9eaead Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 27 Sep 2013 18:48:41 +1000 Subject: [PATCH 59/88] icarus ensure all cmr interfaces are initialised properly --- driver-icarus.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 8ffe3908..59fd5541 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -297,7 +297,7 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud) return; // Latency - usb_ftdi_set_latency(icarus); + _usb_ftdi_set_latency(icarus, info->intinfo); if (icarus->usbinfo.nodev) return; @@ -890,13 +890,6 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices cgtmp->usbinfo.usbstat = USB_NOSTAT; - if (!add_cgpu(cgtmp)) { - usb_uninit(cgtmp); - continue; - } - - update_usb_stats(cgtmp); - intmp = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO)); if (unlikely(!intmp)) quit(1, "Failed2 to malloc ICARUS_INFO"); @@ -907,6 +900,16 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices memcpy(intmp, info, sizeof(struct ICARUS_INFO)); intmp->intinfo = i; + + icarus_initialise(cgtmp, baud); + + if (!add_cgpu(cgtmp)) { + usb_uninit(cgtmp); + free(intmp); + continue; + } + + update_usb_stats(cgtmp); } } From 71797050f2e2c49a37d65dd7f9faf2a16563f6da Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Sep 2013 22:37:14 +1000 Subject: [PATCH 60/88] There is no point setting the BF1 preferred packet size to the maximum since it will do so automatically. --- usbutils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usbutils.c b/usbutils.c index 4bd71179..0a42c71e 100644 --- a/usbutils.c +++ b/usbutils.c @@ -132,12 +132,12 @@ static struct usb_intinfo bfl_ints[] = { #ifdef USE_BITFURY static struct usb_epinfo bfu0_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_INTERRUPT, 8, EPI(2), 0, 8, 0 } + { LIBUSB_TRANSFER_TYPE_INTERRUPT, 8, EPI(2), 0, 0, 0 } }; static struct usb_epinfo bfu1_epinfos[] = { - { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0, 16, 0 }, - { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0, 16, 0 } + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPI(3), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 16, EPO(4), 0, 0, 0 } }; /* Default to interface 1 */ From 8875197466ac8b144d177b954ad396bf73c2b007 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 10:25:48 +1000 Subject: [PATCH 61/88] Create a macro list of drivers to enable easier addition of further drivers. --- api.c | 32 ++++++++++++++++---------------- cgminer.c | 2 +- driver-avalon.c | 2 +- driver-bflsc.c | 2 +- driver-bitforce.c | 2 +- driver-bitfury.c | 2 +- driver-icarus.c | 2 +- driver-modminer.c | 2 +- driver-opencl.c | 10 +++++----- driver-ztex.c | 2 +- miner.h | 22 ++++++++++++++-------- usbutils.c | 24 ++++++++++++------------ 12 files changed, 55 insertions(+), 49 deletions(-) diff --git a/api.c b/api.c index e86ac7b9..e1455433 100644 --- a/api.c +++ b/api.c @@ -1220,15 +1220,15 @@ static int numascs() rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_AVALON - if (devices[i]->drv->drv_id == DRIVER_AVALON) + if (devices[i]->drv->drv_id == DRIVER_avalon) count++; #endif #ifdef USE_BFLSC - if (devices[i]->drv->drv_id == DRIVER_BFLSC) + if (devices[i]->drv->drv_id == DRIVER_bflsc) count++; #endif #ifdef USE_BITFURY - if (devices[i]->drv->drv_id == DRIVER_BITFURY) + if (devices[i]->drv->drv_id == DRIVER_bitfury) count++; #endif } @@ -1244,15 +1244,15 @@ static int ascdevice(int ascid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_AVALON - if (devices[i]->drv->drv_id == DRIVER_AVALON) + if (devices[i]->drv->drv_id == DRIVER_avalon) count++; #endif #ifdef USE_BFLSC - if (devices[i]->drv->drv_id == DRIVER_BFLSC) + if (devices[i]->drv->drv_id == DRIVER_bflsc) count++; #endif #ifdef USE_BITFURY - if (devices[i]->drv->drv_id == DRIVER_BITFURY) + if (devices[i]->drv->drv_id == DRIVER_bitfury) count++; #endif if (count == (ascid + 1)) @@ -1278,19 +1278,19 @@ static int numpgas() rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_BITFORCE - if (devices[i]->drv->drv_id == DRIVER_BITFORCE) + if (devices[i]->drv->drv_id == DRIVER_bitforce) count++; #endif #ifdef USE_ICARUS - if (devices[i]->drv->drv_id == DRIVER_ICARUS) + if (devices[i]->drv->drv_id == DRIVER_icarus) count++; #endif #ifdef USE_ZTEX - if (devices[i]->drv->drv_id == DRIVER_ZTEX) + if (devices[i]->drv->drv_id == DRIVER_ztex) count++; #endif #ifdef USE_MODMINER - if (devices[i]->drv->drv_id == DRIVER_MODMINER) + if (devices[i]->drv->drv_id == DRIVER_modminer) count++; #endif } @@ -1306,19 +1306,19 @@ static int pgadevice(int pgaid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { #ifdef USE_BITFORCE - if (devices[i]->drv->drv_id == DRIVER_BITFORCE) + if (devices[i]->drv->drv_id == DRIVER_bitforce) count++; #endif #ifdef USE_ICARUS - if (devices[i]->drv->drv_id == DRIVER_ICARUS) + if (devices[i]->drv->drv_id == DRIVER_icarus) count++; #endif #ifdef USE_ZTEX - if (devices[i]->drv->drv_id == DRIVER_ZTEX) + if (devices[i]->drv->drv_id == DRIVER_ztex) count++; #endif #ifdef USE_MODMINER - if (devices[i]->drv->drv_id == DRIVER_MODMINER) + if (devices[i]->drv->drv_id == DRIVER_modminer) count++; #endif if (count == (pgaid + 1)) @@ -1770,11 +1770,11 @@ static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom dev_runtime = 1.0; #ifdef USE_ZTEX - if (cgpu->drv->drv_id == DRIVER_ZTEX && cgpu->device_ztex) + if (cgpu->drv->drv_id == DRIVER_ztex && cgpu->device_ztex) frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1); #endif #ifdef USE_MODMINER - if (cgpu->drv->drv_id == DRIVER_MODMINER) + if (cgpu->drv->drv_id == DRIVER_modminer) frequency = cgpu->clock; #endif diff --git a/cgminer.c b/cgminer.c index 953ab027..40219906 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7496,7 +7496,7 @@ void enable_device(struct cgpu_info *cgpu) #endif } #ifdef HAVE_OPENCL - if (cgpu->drv->drv_id == DRIVER_OPENCL) { + if (cgpu->drv->drv_id == DRIVER_opencl) { gpu_threads += cgpu->threads; } #endif diff --git a/driver-avalon.c b/driver-avalon.c index 333add99..0223c620 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -1600,7 +1600,7 @@ static char *avalon_set_device(struct cgpu_info *avalon, char *option, char *set } struct device_drv avalon_drv = { - .drv_id = DRIVER_AVALON, + .drv_id = DRIVER_avalon, .dname = "avalon", .name = "AVA", .drv_detect = avalon_detect, diff --git a/driver-bflsc.c b/driver-bflsc.c index 48cadf23..26cf0c6c 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -1915,7 +1915,7 @@ else a whole lot of something like these ... etc } struct device_drv bflsc_drv = { - .drv_id = DRIVER_BFLSC, + .drv_id = DRIVER_bflsc, .dname = "BitForceSC", .name = BFLSC_SINGLE, .drv_detect = bflsc_detect, diff --git a/driver-bitforce.c b/driver-bitforce.c index 30a6b2dd..2132427a 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -742,7 +742,7 @@ static struct api_data *bitforce_api_stats(struct cgpu_info *cgpu) } struct device_drv bitforce_drv = { - .drv_id = DRIVER_BITFORCE, + .drv_id = DRIVER_bitforce, .dname = "BitForce", .name = "BFL", .drv_detect = bitforce_detect, diff --git a/driver-bitfury.c b/driver-bitfury.c index 71524437..d26ae629 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -310,7 +310,7 @@ static void bitfury_shutdown(struct thr_info *thr) /* Currently hardcoded to BF1 devices */ struct device_drv bitfury_drv = { - .drv_id = DRIVER_BITFURY, + .drv_id = DRIVER_bitfury, .dname = "bitfury", .name = "BF1", .drv_detect = bitfury_detect, diff --git a/driver-icarus.c b/driver-icarus.c index 59fd5541..0dbcbb44 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -1210,7 +1210,7 @@ static void icarus_shutdown(__maybe_unused struct thr_info *thr) } struct device_drv icarus_drv = { - .drv_id = DRIVER_ICARUS, + .drv_id = DRIVER_icarus, .dname = "Icarus", .name = "ICA", .drv_detect = icarus_detect, diff --git a/driver-modminer.c b/driver-modminer.c index 8f85855a..8e7f651d 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -1132,7 +1132,7 @@ static char *modminer_set_device(struct cgpu_info *modminer, char *option, char } struct device_drv modminer_drv = { - .drv_id = DRIVER_MODMINER, + .drv_id = DRIVER_modminer, .dname = "ModMiner", .name = "MMQ", .drv_detect = modminer_detect, diff --git a/driver-opencl.c b/driver-opencl.c index 57df2dcc..0e2aba2e 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -753,7 +753,7 @@ retry: for (i = 0; i < mining_threads; ++i) { thr = get_thread(i); cgpu = thr->cgpu; - if (cgpu->drv->drv_id != DRIVER_OPENCL) + if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(i) != selected) continue; @@ -1148,7 +1148,7 @@ select_cgpu: for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = get_thread(thr_id); cgpu = thr->cgpu; - if (cgpu->drv->drv_id != DRIVER_OPENCL) + if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; @@ -1173,7 +1173,7 @@ select_cgpu: thr = get_thread(thr_id); cgpu = thr->cgpu; - if (cgpu->drv->drv_id != DRIVER_OPENCL) + if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; @@ -1210,7 +1210,7 @@ select_cgpu: for (thr_id = 0; thr_id < mining_threads; ++thr_id) { thr = get_thread(thr_id); cgpu = thr->cgpu; - if (cgpu->drv->drv_id != DRIVER_OPENCL) + if (cgpu->drv->drv_id != DRIVER_opencl) continue; if (dev_from_id(thr_id) != gpu) continue; @@ -1575,7 +1575,7 @@ static void opencl_thread_shutdown(struct thr_info *thr) } struct device_drv opencl_drv = { - .drv_id = DRIVER_OPENCL, + .drv_id = DRIVER_opencl, .dname = "opencl", .name = "GPU", .drv_detect = opencl_detect, diff --git a/driver-ztex.c b/driver-ztex.c index 25254716..38c64904 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -413,7 +413,7 @@ static void ztex_disable(struct thr_info *thr) } struct device_drv ztex_drv = { - .drv_id = DRIVER_ZTEX, + .drv_id = DRIVER_ztex, .dname = "ztex", .name = "ZTX", .drv_detect = ztex_detect, diff --git a/miner.h b/miner.h index 867ca0e6..780b36b0 100644 --- a/miner.h +++ b/miner.h @@ -230,17 +230,23 @@ static inline int fsync (int fd) #define MIN(x, y) ((x) > (y) ? (y) : (x)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) +#define DRIVER_PARSE_COMMANDS \ + DRIVER_ADD_COMMAND(avalon) \ + DRIVER_ADD_COMMAND(bflsc) \ + DRIVER_ADD_COMMAND(bitforce) \ + DRIVER_ADD_COMMAND(bitfury) \ + DRIVER_ADD_COMMAND(icarus) \ + DRIVER_ADD_COMMAND(modminer) \ + DRIVER_ADD_COMMAND(opencl) \ + DRIVER_ADD_COMMAND(ztex) + +/* Create drv_driver enum from DRIVER_PARSE_COMMANDS macro */ +#define DRIVER_ADD_COMMAND(X) DRIVER_##X, enum drv_driver { - DRIVER_OPENCL = 0, - DRIVER_ICARUS, - DRIVER_BITFORCE, - DRIVER_BITFURY, - DRIVER_MODMINER, - DRIVER_ZTEX, - DRIVER_BFLSC, - DRIVER_AVALON, + DRIVER_PARSE_COMMANDS DRIVER_MAX }; +#undef DRIVER_ADD_COMMAND enum alive { LIFE_WELL, diff --git a/usbutils.c b/usbutils.c index 136e93e8..28933ef7 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1899,32 +1899,32 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, } #ifdef USE_BFLSC - if (drv->drv_id == DRIVER_BFLSC) + if (drv->drv_id == DRIVER_bflsc) return usb_check_each(DRV_BFLSC, drv, dev); #endif #ifdef USE_BITFORCE - if (drv->drv_id == DRIVER_BITFORCE) + if (drv->drv_id == DRIVER_bitforce) return usb_check_each(DRV_BITFORCE, drv, dev); #endif #ifdef USE_BITFURY - if (drv->drv_id == DRIVER_BITFURY) + if (drv->drv_id == DRIVER_bitfury) return usb_check_each(DRV_BITFURY, drv, dev); #endif #ifdef USE_MODMINER - if (drv->drv_id == DRIVER_MODMINER) + if (drv->drv_id == DRIVER_modminer) return usb_check_each(DRV_MODMINER, drv, dev); #endif #ifdef USE_ICARUS - if (drv->drv_id == DRIVER_ICARUS) + if (drv->drv_id == DRIVER_icarus) return usb_check_each(DRV_ICARUS, drv, dev); #endif #ifdef USE_AVALON - if (drv->drv_id == DRIVER_AVALON) + if (drv->drv_id == DRIVER_avalon) return usb_check_each(DRV_AVALON, drv, dev); #endif @@ -3151,12 +3151,12 @@ void usb_cleanup() for (i = 0; i < total_devices; i++) { cgpu = devices[i]; switch (cgpu->drv->drv_id) { - case DRIVER_BFLSC: - case DRIVER_BITFORCE: - case DRIVER_BITFURY: - case DRIVER_MODMINER: - case DRIVER_ICARUS: - case DRIVER_AVALON: + case DRIVER_bflsc: + case DRIVER_bitforce: + case DRIVER_bitfury: + case DRIVER_modminer: + case DRIVER_icarus: + case DRIVER_avalon: wr_lock(cgpu->usbinfo.devlock); release_cgpu(cgpu); wr_unlock(cgpu->usbinfo.devlock); From 2903028e6b6228366d270b6b673b5e6961a64a49 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 11:45:58 +1000 Subject: [PATCH 62/88] Use macro expansion to generate extern device_drv prototypes. --- miner.h | 5 +++++ usbutils.c | 24 ------------------------ 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/miner.h b/miner.h index 780b36b0..bf932dde 100644 --- a/miner.h +++ b/miner.h @@ -248,6 +248,11 @@ enum drv_driver { }; #undef DRIVER_ADD_COMMAND +/* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */ +#define DRIVER_ADD_COMMAND(X) extern struct device_drv X##_drv; +DRIVER_PARSE_COMMANDS; +#undef DRIVER_ADD_COMMAND + enum alive { LIFE_WELL, LIFE_SICK, diff --git a/usbutils.c b/usbutils.c index 28933ef7..2a20b7fe 100644 --- a/usbutils.c +++ b/usbutils.c @@ -406,30 +406,6 @@ static struct usb_find_devices find_dev[] = { { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, NULL } }; -#ifdef USE_BFLSC -extern struct device_drv bflsc_drv; -#endif - -#ifdef USE_BITFORCE -extern struct device_drv bitforce_drv; -#endif - -#ifdef USE_BITFURY -extern struct device_drv bitfury_drv; -#endif - -#ifdef USE_MODMINER -extern struct device_drv modminer_drv; -#endif - -#ifdef USE_ICARUS -extern struct device_drv icarus_drv; -#endif - -#ifdef USE_AVALON -extern struct device_drv avalon_drv; -#endif - #define STRBUFLEN 256 static const char *BLANK = ""; static const char *space = " "; From 372c40956a8307f6adcec77573a0990822ba5877 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 12:44:36 +1000 Subject: [PATCH 63/88] Reuse the DRIVER_ macros to avoid having yet another definition for DRV_ --- usbutils.c | 76 +++++++++++++++++------------------------------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/usbutils.c b/usbutils.c index 2a20b7fe..bb396183 100644 --- a/usbutils.c +++ b/usbutils.c @@ -42,36 +42,6 @@ pthread_setcancelstate(_pth_state, NULL); \ } while (0) -#ifdef USE_BFLSC -#define DRV_BFLSC 1 -#endif - -#ifdef USE_BITFORCE -#define DRV_BITFORCE 2 -#endif - -#ifdef USE_MODMINER -#define DRV_MODMINER 3 -#endif - -#ifdef USE_ZTEX -#define DRV_ZTEX 4 -#endif - -#ifdef USE_ICARUS -#define DRV_ICARUS 5 -#endif - -#ifdef USE_AVALON -#define DRV_AVALON 6 -#endif - -#ifdef USE_BITFURY -#define DRV_BITFURY 8 -#endif - -#define DRV_LAST -1 - #define USB_CONFIG 1 #ifdef WIN32 @@ -245,7 +215,7 @@ static struct usb_intinfo cmr2_ints[] = { static struct usb_find_devices find_dev[] = { #ifdef USE_BFLSC { - .drv = DRV_BFLSC, + .drv = DRIVER_bflsc, .name = "BAS", .ident = IDENT_BAS, .idVendor = IDVENDOR_FTDI, @@ -259,7 +229,7 @@ static struct usb_find_devices find_dev[] = { #endif #ifdef USE_BITFORCE { - .drv = DRV_BITFORCE, + .drv = DRIVER_bitforce, .name = "BFL", .ident = IDENT_BFL, .idVendor = IDVENDOR_FTDI, @@ -273,7 +243,7 @@ static struct usb_find_devices find_dev[] = { #endif #ifdef USE_BITFURY { - .drv = DRV_BITFURY, + .drv = DRIVER_bitfury, .name = "BF1", .ident = IDENT_BFU, .idVendor = 0x03eb, @@ -288,7 +258,7 @@ static struct usb_find_devices find_dev[] = { #endif #ifdef USE_MODMINER { - .drv = DRV_MODMINER, + .drv = DRIVER_modminer, .name = "MMQ", .ident = IDENT_MMQ, .idVendor = 0x1fc9, @@ -300,7 +270,7 @@ static struct usb_find_devices find_dev[] = { #endif #ifdef USE_AVALON { - .drv = DRV_AVALON, + .drv = DRIVER_avalon, .name = "BTB", .ident = IDENT_BTB, .idVendor = IDVENDOR_FTDI, @@ -312,7 +282,7 @@ static struct usb_find_devices find_dev[] = { .latency = 10, INTINFO(ava_ints) }, { - .drv = DRV_AVALON, + .drv = DRIVER_avalon, .name = "AVA", .ident = IDENT_AVA, .idVendor = IDVENDOR_FTDI, @@ -324,7 +294,7 @@ static struct usb_find_devices find_dev[] = { #endif #ifdef USE_ICARUS { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "ICA", .ident = IDENT_ICA, .idVendor = 0x067b, @@ -334,7 +304,7 @@ static struct usb_find_devices find_dev[] = { .latency = LATENCY_UNUSED, INTINFO(ica_ints) }, { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "AMU", .ident = IDENT_AMU, .idVendor = 0x10c4, @@ -344,7 +314,7 @@ static struct usb_find_devices find_dev[] = { .latency = LATENCY_UNUSED, INTINFO(amu_ints) }, { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "BLT", .ident = IDENT_BLT, .idVendor = IDVENDOR_FTDI, @@ -356,7 +326,7 @@ static struct usb_find_devices find_dev[] = { INTINFO(llt_ints) }, // For any that don't match the above "BLT" { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "LLT", .ident = IDENT_LLT, .idVendor = IDVENDOR_FTDI, @@ -366,7 +336,7 @@ static struct usb_find_devices find_dev[] = { .latency = LATENCY_STD, INTINFO(llt_ints) }, { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "CMR", .ident = IDENT_CMR1, .idVendor = IDVENDOR_FTDI, @@ -377,7 +347,7 @@ static struct usb_find_devices find_dev[] = { .latency = LATENCY_STD, INTINFO(cmr1_ints) }, { - .drv = DRV_ICARUS, + .drv = DRIVER_icarus, .name = "CMR", .ident = IDENT_CMR2, .idVendor = IDVENDOR_FTDI, @@ -392,7 +362,7 @@ static struct usb_find_devices find_dev[] = { // This is here so cgminer -n shows them // the ztex driver (as at 201303) doesn't use usbutils { - .drv = DRV_ZTEX, + .drv = DRIVER_ztex, .name = "ZTX", .ident = IDENT_ZTX, .idVendor = 0x221a, @@ -403,7 +373,7 @@ static struct usb_find_devices find_dev[] = { .intinfo_count = 0, .intinfos = NULL }, #endif - { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, NULL } + { DRIVER_MAX, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, NULL } }; #define STRBUFLEN 256 @@ -787,7 +757,7 @@ static void usb_full(ssize_t *count, libusb_device *dev, char **buf, size_t *off if (!opt_usb_list_all) { bool known = false; - for (i = 0; find_dev[i].drv != DRV_LAST; i++) + for (i = 0; find_dev[i].drv != DRIVER_MAX; i++) if ((find_dev[i].idVendor == desc.idVendor) && (find_dev[i].idProduct == desc.idProduct)) { known = true; @@ -1774,7 +1744,7 @@ bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find int uninitialised_var(ret); int i; - for (i = 0; find_dev[i].drv != DRV_LAST; i++) { + for (i = 0; find_dev[i].drv != DRIVER_MAX; i++) { if (find_dev[i].drv == found_match->drv && find_dev[i].idVendor == found_match->idVendor && find_dev[i].idProduct == found_match->idProduct) { @@ -1851,7 +1821,7 @@ static struct usb_find_devices *usb_check_each(int drvnum, struct device_drv *dr struct usb_find_devices *found; int i; - for (i = 0; find_dev[i].drv != DRV_LAST; i++) + for (i = 0; find_dev[i].drv != DRIVER_MAX; i++) if (find_dev[i].drv == drvnum) { if (usb_check_device(drv, dev, &(find_dev[i]))) { found = malloc(sizeof(*found)); @@ -1876,32 +1846,32 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, #ifdef USE_BFLSC if (drv->drv_id == DRIVER_bflsc) - return usb_check_each(DRV_BFLSC, drv, dev); + return usb_check_each(DRIVER_bflsc, drv, dev); #endif #ifdef USE_BITFORCE if (drv->drv_id == DRIVER_bitforce) - return usb_check_each(DRV_BITFORCE, drv, dev); + return usb_check_each(DRIVER_bitforce, drv, dev); #endif #ifdef USE_BITFURY if (drv->drv_id == DRIVER_bitfury) - return usb_check_each(DRV_BITFURY, drv, dev); + return usb_check_each(DRIVER_bitfury, drv, dev); #endif #ifdef USE_MODMINER if (drv->drv_id == DRIVER_modminer) - return usb_check_each(DRV_MODMINER, drv, dev); + return usb_check_each(DRIVER_modminer, drv, dev); #endif #ifdef USE_ICARUS if (drv->drv_id == DRIVER_icarus) - return usb_check_each(DRV_ICARUS, drv, dev); + return usb_check_each(DRIVER_icarus, drv, dev); #endif #ifdef USE_AVALON if (drv->drv_id == DRIVER_avalon) - return usb_check_each(DRV_AVALON, drv, dev); + return usb_check_each(DRIVER_avalon, drv, dev); #endif return NULL; From df54b7685599ec5705978e419a36c4a6bf796de4 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 13:52:13 +1000 Subject: [PATCH 64/88] Add a noop function for driver detect when it's missing. --- cgminer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cgminer.c b/cgminer.c index 40219906..6fad18e9 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7434,6 +7434,9 @@ static void noop_thread_enable(struct thr_info __maybe_unused *thr) { } +static void noop_null(void) +{ +} #define noop_flush_work noop_reinit_device #define noop_queue_full noop_get_stats @@ -7442,6 +7445,8 @@ void fill_device_drv(struct cgpu_info *cgpu) { struct device_drv *drv = cgpu->drv; + if (!drv->drv_detect) + drv->drv_detect = &noop_null; if (!drv->reinit_device) drv->reinit_device = &noop_reinit_device; if (!drv->get_statline_before) From 741b74309ef8d804eedf616350bc3616a7cf25ae Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 14:00:18 +1000 Subject: [PATCH 65/88] Forward declare all device drivers in miner.h avoiding the need to export them everywhere else. --- driver-avalon.c | 1 - driver-bflsc.c | 2 -- driver-bitforce.c | 2 -- driver-bitfury.c | 1 - driver-icarus.c | 2 -- driver-modminer.c | 2 -- driver-opencl.c | 4 ---- driver-ztex.c | 2 -- miner.h | 2 +- 9 files changed, 1 insertion(+), 17 deletions(-) diff --git a/driver-avalon.c b/driver-avalon.c index 0223c620..d6cd71d1 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -52,7 +52,6 @@ int opt_bitburner_core_voltage = BITBURNER_DEFAULT_CORE_VOLTAGE; bool opt_avalon_auto; static int option_offset = -1; -struct device_drv avalon_drv; static int avalon_init_task(struct avalon_task *at, uint8_t reset, uint8_t ff, uint8_t fan, diff --git a/driver-bflsc.c b/driver-bflsc.c index 26cf0c6c..5ace03d3 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -33,8 +33,6 @@ int opt_bflsc_overheat = BFLSC_TEMP_OVERHEAT; static const char *blank = ""; -struct device_drv bflsc_drv; - static enum driver_version drv_ver(struct cgpu_info *bflsc, const char *ver) { char *tmp; diff --git a/driver-bitforce.c b/driver-bitforce.c index 2132427a..f28dc1e8 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -77,8 +77,6 @@ static const char *blank = ""; -struct device_drv bitforce_drv; - static void bitforce_initialise(struct cgpu_info *bitforce, bool lock) { int err, interface; diff --git a/driver-bitfury.c b/driver-bitfury.c index d26ae629..0d72b916 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -15,7 +15,6 @@ /* Wait longer 1/3 longer than it would take for a full nonce range */ #define BF1WAIT 1600 -struct device_drv bitfury_drv; static void bitfury_empty_buffer(struct cgpu_info *bitfury) { diff --git a/driver-icarus.c b/driver-icarus.c index 0dbcbb44..0773ad57 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -235,8 +235,6 @@ struct ICARUS_INFO { // static int option_offset = -1; -struct device_drv icarus_drv; - /* #define ICA_BUFSIZ (0x200) diff --git a/driver-modminer.c b/driver-modminer.c index 8e7f651d..3a809861 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -87,8 +87,6 @@ // Limit when reducing shares_to_good #define MODMINER_MIN_BACK 12 -struct device_drv modminer_drv; - // 45 noops sent when detecting, in case the device was left in "start job" reading static const char NOOP[] = MODMINER_PING "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; diff --git a/driver-opencl.c b/driver-opencl.c index 0e2aba2e..b6ad37dd 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -56,10 +56,6 @@ extern void decay_time(double *f, double fadd); /**********************************************/ -#ifdef HAVE_OPENCL -struct device_drv opencl_drv; -#endif - #ifdef HAVE_ADL extern float gpu_temp(int gpu); extern int gpu_fanspeed(int gpu); diff --git a/driver-ztex.c b/driver-ztex.c index 38c64904..f806717f 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -31,8 +31,6 @@ #define GOLDEN_BACKLOG 5 -struct device_drv ztex_drv; - // Forward declarations static void ztex_disable(struct thr_info* thr); static bool ztex_prepare(struct thr_info *thr); diff --git a/miner.h b/miner.h index bf932dde..1dddf3da 100644 --- a/miner.h +++ b/miner.h @@ -249,7 +249,7 @@ enum drv_driver { #undef DRIVER_ADD_COMMAND /* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */ -#define DRIVER_ADD_COMMAND(X) extern struct device_drv X##_drv; +#define DRIVER_ADD_COMMAND(X) struct device_drv X##_drv; DRIVER_PARSE_COMMANDS; #undef DRIVER_ADD_COMMAND From 6d7471237dd8bbc2666e9bf3a9dc45e00097ebc9 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 15:11:06 +1000 Subject: [PATCH 66/88] Use macro expansion to iterate over all device drivers without needing to explicitly code in support in all places. Pass a hotplug bool to the detect() function to prevent opencl trying to hogplug GPUs. --- cgminer.c | 94 +++++++++++------------------------------------ driver-avalon.c | 2 +- driver-bflsc.c | 2 +- driver-bitforce.c | 2 +- driver-bitfury.c | 2 +- driver-icarus.c | 2 +- driver-modminer.c | 2 +- driver-opencl.c | 6 ++- driver-ztex.c | 2 +- miner.h | 3 +- 10 files changed, 35 insertions(+), 82 deletions(-) diff --git a/cgminer.c b/cgminer.c index 6fad18e9..9f39a7ec 100644 --- a/cgminer.c +++ b/cgminer.c @@ -119,7 +119,7 @@ bool opt_scrypt; #endif #endif bool opt_restart = true; -static bool opt_nogpu; +bool opt_nogpu; struct list_head scan_devices; static bool devices_enabled[MAX_DEVICES]; @@ -7434,19 +7434,17 @@ static void noop_thread_enable(struct thr_info __maybe_unused *thr) { } -static void noop_null(void) +static void noop_detect(bool __maybe_unused hotplug) { } #define noop_flush_work noop_reinit_device #define noop_queue_full noop_get_stats /* Fill missing driver drv functions with noops */ -void fill_device_drv(struct cgpu_info *cgpu) +void fill_device_drv(struct device_drv *drv) { - struct device_drv *drv = cgpu->drv; - if (!drv->drv_detect) - drv->drv_detect = &noop_null; + drv->drv_detect = &noop_detect; if (!drv->reinit_device) drv->reinit_device = &noop_reinit_device; if (!drv->get_statline_before) @@ -7544,8 +7542,6 @@ bool add_cgpu(struct cgpu_info *cgpu) cgpu->last_device_valid_work = time(NULL); mutex_unlock(&stats_lock); - fill_device_drv(cgpu); - if (hotplug_mode) devices[total_devices + new_devices++] = cgpu; else @@ -7655,29 +7651,11 @@ static void *hotplug_thread(void __maybe_unused *userdata) new_devices = 0; new_threads = 0; -#ifdef USE_ICARUS - icarus_drv.drv_detect(); -#endif - -#ifdef USE_BFLSC - bflsc_drv.drv_detect(); -#endif - -#ifdef USE_BITFORCE - bitforce_drv.drv_detect(); -#endif - -#ifdef USE_BITFURY - bitfury_drv.drv_detect(); -#endif - -#ifdef USE_MODMINER - modminer_drv.drv_detect(); -#endif - -#ifdef USE_AVALON - avalon_drv.drv_detect(); -#endif + /* Use the DRIVER_PARSE_COMMANDS macro to detect all + * devices */ +#define DRIVER_ADD_COMMAND(X) X##_drv.drv_detect(true); + DRIVER_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND if (new_devices) hotplug_process(); @@ -7883,48 +7861,20 @@ int main(int argc, char *argv[]) } #endif -#ifdef HAVE_OPENCL - if (!opt_nogpu) - opencl_drv.drv_detect(); - gpu_threads = 0; -#endif + /* Use the DRIVER_PARSE_COMMANDS macro to fill all the device_drvs */ +#define DRIVER_ADD_COMMAND(X) fill_device_drv(&X##_drv); + DRIVER_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND -#ifdef USE_ICARUS - if (!opt_scrypt) - icarus_drv.drv_detect(); -#endif - -#ifdef USE_BFLSC - if (!opt_scrypt) - bflsc_drv.drv_detect(); -#endif - -#ifdef USE_BITFORCE - if (!opt_scrypt) - bitforce_drv.drv_detect(); -#endif - -#ifdef USE_BITFURY - if (!opt_scrypt) - bitfury_drv.drv_detect(); -#endif - -#ifdef USE_MODMINER - if (!opt_scrypt) - modminer_drv.drv_detect(); -#endif - -#ifdef USE_ZTEX - if (!opt_scrypt) - ztex_drv.drv_detect(); -#endif - - /* Detect avalon last since it will try to claim the device regardless - * as detection is unreliable. */ -#ifdef USE_AVALON - if (!opt_scrypt) - avalon_drv.drv_detect(); -#endif + if (opt_scrypt) + opencl_drv.drv_detect(false); + else { + /* Use the DRIVER_PARSE_COMMANDS macro to detect all devices */ +#define DRIVER_ADD_COMMAND(X) X##_drv.drv_detect(false); + DRIVER_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND + } + gpu_threads = 0; if (opt_display_devs) { applog(LOG_ERR, "Devices detected:"); diff --git a/driver-avalon.c b/driver-avalon.c index d6cd71d1..6abdaeb4 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -799,7 +799,7 @@ shin: return false; } -static void avalon_detect(void) +static void avalon_detect(bool __maybe_unused hotplug) { usb_detect(&avalon_drv, avalon_detect_one); } diff --git a/driver-bflsc.c b/driver-bflsc.c index 5ace03d3..bebed38b 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -893,7 +893,7 @@ shin: return false; } -static void bflsc_detect(void) +static void bflsc_detect(bool __maybe_unused hotplug) { usb_detect(&bflsc_drv, bflsc_detect_one); } diff --git a/driver-bitforce.c b/driver-bitforce.c index f28dc1e8..6cd0d52e 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -288,7 +288,7 @@ shin: return false; } -static void bitforce_detect(void) +static void bitforce_detect(bool __maybe_unused hotplug) { usb_detect(&bitforce_drv, bitforce_detect_one); } diff --git a/driver-bitfury.c b/driver-bitfury.c index 0d72b916..9708fe6d 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -150,7 +150,7 @@ out: return false; } -static void bitfury_detect(void) +static void bitfury_detect(bool __maybe_unused hotplug) { usb_detect(&bitfury_drv, bitfury_detect_one); } diff --git a/driver-icarus.c b/driver-icarus.c index 0773ad57..a42988bb 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -926,7 +926,7 @@ shin: return false; } -static void icarus_detect() +static void icarus_detect(bool __maybe_unused hotplug) { usb_detect(&icarus_drv, icarus_detect_one); } diff --git a/driver-modminer.c b/driver-modminer.c index 3a809861..0672c994 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -237,7 +237,7 @@ shin: return false; } -static void modminer_detect() +static void modminer_detect(bool __maybe_unused hotplug) { usb_detect(&modminer_drv, modminer_detect_one); } diff --git a/driver-opencl.c b/driver-opencl.c index b6ad37dd..d7b663a9 100644 --- a/driver-opencl.c +++ b/driver-opencl.c @@ -581,7 +581,7 @@ char *set_intensity(char *arg) void print_ndevs(int *ndevs) { opt_log_output = true; - opencl_drv.drv_detect(); + opencl_drv.drv_detect(false); clear_adl(*ndevs); applog(LOG_INFO, "%i GPU devices max detected", *ndevs); } @@ -1227,10 +1227,12 @@ void *reinit_gpu(__maybe_unused void *userdata) #ifdef HAVE_OPENCL -static void opencl_detect() +static void opencl_detect(bool hotplug) { int i; + if (opt_nogpu || hotplug) + return; nDevs = clDevicesNum(); if (nDevs < 0) { applog(LOG_ERR, "clDevicesNum returned error, no GPUs usable"); diff --git a/driver-ztex.c b/driver-ztex.c index f806717f..ee0c0a9b 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -52,7 +52,7 @@ static void ztex_releaseFpga(struct libztex_device* ztex) } } -static void ztex_detect(void) +static void ztex_detect(bool __maybe_unused hotplug) { int cnt; int i,j; diff --git a/miner.h b/miner.h index 1dddf3da..be92b833 100644 --- a/miner.h +++ b/miner.h @@ -329,7 +329,7 @@ struct device_drv { char *name; // DRV-global functions - void (*drv_detect)(); + void (*drv_detect)(bool); // Device-specific functions void (*reinit_device)(struct cgpu_info *); @@ -914,6 +914,7 @@ extern bool opt_api_listen; extern bool opt_api_network; extern bool opt_delaynet; extern bool opt_restart; +extern bool opt_nogpu; extern char *opt_icarus_options; extern char *opt_icarus_timing; extern bool opt_worktime; From fbf46c41b3748bb68a91ec3b9e2510c9dcd6e8a7 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 15:14:28 +1000 Subject: [PATCH 67/88] Put avalon last in the sequence of adding drivers to prevent it trying to claim similar chip devices on startup. --- miner.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/miner.h b/miner.h index be92b833..cdd41ad1 100644 --- a/miner.h +++ b/miner.h @@ -230,15 +230,17 @@ static inline int fsync (int fd) #define MIN(x, y) ((x) > (y) ? (y) : (x)) #define MAX(x, y) ((x) > (y) ? (x) : (y)) +/* Put avalon last to make it the last device it tries to detect to prevent it + * trying to claim same chip but different devices. */ #define DRIVER_PARSE_COMMANDS \ - DRIVER_ADD_COMMAND(avalon) \ DRIVER_ADD_COMMAND(bflsc) \ DRIVER_ADD_COMMAND(bitforce) \ DRIVER_ADD_COMMAND(bitfury) \ DRIVER_ADD_COMMAND(icarus) \ DRIVER_ADD_COMMAND(modminer) \ DRIVER_ADD_COMMAND(opencl) \ - DRIVER_ADD_COMMAND(ztex) + DRIVER_ADD_COMMAND(ztex) \ + DRIVER_ADD_COMMAND(avalon) /* Create drv_driver enum from DRIVER_PARSE_COMMANDS macro */ #define DRIVER_ADD_COMMAND(X) DRIVER_##X, From f3294f7424fe170b6b6947bf79e3719a56c2cc57 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 15:18:08 +1000 Subject: [PATCH 68/88] Remove unnecessary gpu_threads initialisation. --- cgminer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 9f39a7ec..458b156a 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7874,7 +7874,6 @@ int main(int argc, char *argv[]) DRIVER_PARSE_COMMANDS #undef DRIVER_ADD_COMMAND } - gpu_threads = 0; if (opt_display_devs) { applog(LOG_ERR, "Devices detected:"); From 2ec601e1236dec5ea60a900afe8831f50346a422 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 16:00:55 +1000 Subject: [PATCH 69/88] There is no need to get the external prototypes for drivers in cgminer.c any more. --- cgminer.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/cgminer.c b/cgminer.c index 458b156a..19f2a0d1 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7352,34 +7352,6 @@ void enable_curses(void) { } #endif -#ifdef USE_BFLSC -extern struct device_drv bflsc_drv; -#endif - -#ifdef USE_BITFORCE -extern struct device_drv bitforce_drv; -#endif - -#ifdef USE_BITFURY -extern struct device_drv bitfury_drv; -#endif - -#ifdef USE_ICARUS -extern struct device_drv icarus_drv; -#endif - -#ifdef USE_AVALON -extern struct device_drv avalon_drv; -#endif - -#ifdef USE_MODMINER -extern struct device_drv modminer_drv; -#endif - -#ifdef USE_ZTEX -extern struct device_drv ztex_drv; -#endif - static int cgminer_id_count = 0; /* Various noop functions for drivers that don't support or need their From 00aa8b4ecf4fb666dc0376fba17a0b528bd929c7 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 23:05:39 +1000 Subject: [PATCH 70/88] libusb kernel driver operations are only available on linux. --- usbutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usbutils.c b/usbutils.c index bb396183..8fff8472 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1490,7 +1490,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u goto dame; } -#ifndef WIN32 +#ifdef LINUX for (ifinfo = 0; ifinfo < found->intinfo_count; ifinfo++) { if (libusb_kernel_driver_active(cgusb->handle, THISIF(found, ifinfo)) == 1) { applog(LOG_DEBUG, "USB init, kernel attached ... %s", devstr); From 3ef9fa3b88b60bd0d123a747b4ef6e75f0cd317b Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 23:09:26 +1000 Subject: [PATCH 71/88] Attach the kernel driver on failure to usb init on linux. --- usbutils.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/usbutils.c b/usbutils.c index 8fff8472..7c335991 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1505,7 +1505,7 @@ static int _usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct u "USB init, kernel detach ifinfo %d interface %d failed," " err %d in use? %s", ifinfo, THISIF(found, ifinfo), err, devstr); - goto cldame; + goto nokernel; } } } @@ -1719,7 +1719,11 @@ reldame: libusb_release_interface(cgusb->handle, THISIF(found, ifinfo)); cldame: +#ifdef LINUX + libusb_attach_kernel_driver(cgusb->handle, THISIF(found, ifinfo)); +nokernel: +#endif cg_wlock(&cgusb_fd_lock); libusb_close(cgusb->handle); cgusb->handle = NULL; From 39c2e662a76c86a94d486ba0ea8f752ad5bf3983 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sat, 28 Sep 2013 23:12:29 +1000 Subject: [PATCH 72/88] Reattach the kernel driver on linux on usb_uninit. --- usbutils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usbutils.c b/usbutils.c index 7c335991..909cd37c 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1273,6 +1273,9 @@ static void _usb_uninit(struct cgpu_info *cgpu) libusb_release_interface(cgpu->usbdev->handle, THISIF(cgpu->usbdev->found, ifinfo)); } +#ifdef LINUX + libusb_attach_kernel_driver(cgpu->usbdev->handle, THISIF(cgpu->usbdev->found, ifinfo)); +#endif cg_wlock(&cgusb_fd_lock); libusb_close(cgpu->usbdev->handle); cgpu->usbdev->handle = NULL; From e279bc1fc5ead5f7badbb7e5d0031d9244498ce1 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sun, 29 Sep 2013 02:20:38 +1000 Subject: [PATCH 73/88] Iterate over the bitfury offsets in order of decreasing likelihood. --- driver-bitfury.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-bitfury.c b/driver-bitfury.c index 9708fe6d..6bb4e8c3 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -178,7 +178,7 @@ static uint32_t decnonce(uint32_t in) } #define BT_OFFSETS 3 -const uint32_t bf_offsets[] = {0, -0x400000, -0x800000}; +const uint32_t bf_offsets[] = {-0x800000, 0, -0x400000}; static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce) { From 0952a8812ffcfa22fc5f613fdca527175ffc5c6b Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sun, 29 Sep 2013 02:45:45 +1000 Subject: [PATCH 74/88] Use macro expansion to iterate over all the drivers without explicitly writing them out in usbutils.c --- usbutils.c | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/usbutils.c b/usbutils.c index 909cd37c..54b90549 100644 --- a/usbutils.c +++ b/usbutils.c @@ -3234,42 +3234,14 @@ void usb_initialise() quit(1, "Invalid --usb DRV:limit - limit must be >= 0"); found = false; -#ifdef USE_BFLSC - if (strcasecmp(ptr, bflsc_drv.name) == 0) { - drv_count[bflsc_drv.drv_id].limit = lim; - found = true; + /* Use the DRIVER_PARSE_COMMANDS macro to iterate + * over all the drivers. */ +#define DRIVER_ADD_COMMAND(X) if (strcasecmp(ptr, X##_drv.name) == 0) { \ + drv_count[X##_drv.drv_id].limit = lim; \ + found = true; \ } -#endif -#ifdef USE_BITFORCE - if (!found && strcasecmp(ptr, bitforce_drv.name) == 0) { - drv_count[bitforce_drv.drv_id].limit = lim; - found = true; - } -#endif -#ifdef USE_BITFURY - if (!found && strcasecmp(ptr, bitfury_drv.name) == 0) { - drv_count[bitfury_drv.drv_id].limit = lim; - found = true; - } -#endif -#ifdef USE_MODMINER - if (!found && strcasecmp(ptr, modminer_drv.name) == 0) { - drv_count[modminer_drv.drv_id].limit = lim; - found = true; - } -#endif -#ifdef USE_ICARUS - if (!found && strcasecmp(ptr, icarus_drv.name) == 0) { - drv_count[icarus_drv.drv_id].limit = lim; - found = true; - } -#endif -#ifdef USE_AVALON - if (!found && strcasecmp(ptr, avalon_drv.name) == 0) { - drv_count[avalon_drv.drv_id].limit = lim; - found = true; - } -#endif + DRIVER_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND if (!found) quit(1, "Invalid --usb DRV:limit - unknown DRV='%s'", ptr); From 8b341ccd60e0b5c1695ce9fff6dd2f16b4af46ac Mon Sep 17 00:00:00 2001 From: ckolivas Date: Sun, 29 Sep 2013 02:48:39 +1000 Subject: [PATCH 75/88] Use macro expansion in usb_find_devices to avoid explicitly listing them all. --- usbutils.c | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) diff --git a/usbutils.c b/usbutils.c index 54b90549..c428b042 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1851,35 +1851,11 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, return NULL; } -#ifdef USE_BFLSC - if (drv->drv_id == DRIVER_bflsc) - return usb_check_each(DRIVER_bflsc, drv, dev); -#endif - -#ifdef USE_BITFORCE - if (drv->drv_id == DRIVER_bitforce) - return usb_check_each(DRIVER_bitforce, drv, dev); -#endif - -#ifdef USE_BITFURY - if (drv->drv_id == DRIVER_bitfury) - return usb_check_each(DRIVER_bitfury, drv, dev); -#endif - -#ifdef USE_MODMINER - if (drv->drv_id == DRIVER_modminer) - return usb_check_each(DRIVER_modminer, drv, dev); -#endif - -#ifdef USE_ICARUS - if (drv->drv_id == DRIVER_icarus) - return usb_check_each(DRIVER_icarus, drv, dev); -#endif - -#ifdef USE_AVALON - if (drv->drv_id == DRIVER_avalon) - return usb_check_each(DRIVER_avalon, drv, dev); -#endif +#define DRIVER_ADD_COMMAND(X) \ + if (drv->drv_id == DRIVER_##X) \ + return usb_check_each(DRIVER_##X, drv, dev); + DRIVER_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND return NULL; } From 1ef38f82e8a507261701e755405474bf0db562dc Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 12:28:43 +1000 Subject: [PATCH 76/88] Separate out asic fpga and opencl drivers in the driver parse commands macro for use individually as needed. --- miner.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/miner.h b/miner.h index cdd41ad1..42f97437 100644 --- a/miner.h +++ b/miner.h @@ -231,17 +231,25 @@ static inline int fsync (int fd) #define MAX(x, y) ((x) > (y) ? (x) : (y)) /* Put avalon last to make it the last device it tries to detect to prevent it - * trying to claim same chip but different devices. */ -#define DRIVER_PARSE_COMMANDS \ - DRIVER_ADD_COMMAND(bflsc) \ + * trying to claim same chip but different devices. Adding a device here will + * update all macros in the code that use the *_PARSE_COMMANDS macros for each + * listed driver. */ +#define FPGA_PARSE_COMMANDS \ DRIVER_ADD_COMMAND(bitforce) \ - DRIVER_ADD_COMMAND(bitfury) \ DRIVER_ADD_COMMAND(icarus) \ DRIVER_ADD_COMMAND(modminer) \ - DRIVER_ADD_COMMAND(opencl) \ - DRIVER_ADD_COMMAND(ztex) \ + DRIVER_ADD_COMMAND(ztex) + +#define ASIC_PARSE_COMMANDS \ + DRIVER_ADD_COMMAND(bflsc) \ + DRIVER_ADD_COMMAND(bitfury) \ DRIVER_ADD_COMMAND(avalon) +#define DRIVER_PARSE_COMMANDS \ + DRIVER_ADD_COMMAND(opencl) \ + FPGA_PARSE_COMMANDS \ + ASIC_PARSE_COMMANDS + /* Create drv_driver enum from DRIVER_PARSE_COMMANDS macro */ #define DRIVER_ADD_COMMAND(X) DRIVER_##X, enum drv_driver { From 55f29b81797f2b679da7f9bf898c9124eac3ae5b Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 12:33:52 +1000 Subject: [PATCH 77/88] Use the driver add commands macros in api.c to avoid individually listing them. --- api.c | 72 +++++++++++++++-------------------------------------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/api.c b/api.c index e1455433..75c1c4f1 100644 --- a/api.c +++ b/api.c @@ -1212,25 +1212,18 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson } #ifdef HAVE_AN_ASIC -static int numascs() +static int numascs(void) { int count = 0; int i; rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_AVALON - if (devices[i]->drv->drv_id == DRIVER_avalon) - count++; -#endif -#ifdef USE_BFLSC - if (devices[i]->drv->drv_id == DRIVER_bflsc) - count++; -#endif -#ifdef USE_BITFURY - if (devices[i]->drv->drv_id == DRIVER_bitfury) +#define DRIVER_ADD_COMMAND(X) \ + if (devices[i]->drv->drv_id == DRIVER_##X) \ count++; -#endif + ASIC_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND } rd_unlock(&devices_lock); return count; @@ -1243,18 +1236,11 @@ static int ascdevice(int ascid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_AVALON - if (devices[i]->drv->drv_id == DRIVER_avalon) +#define DRIVER_ADD_COMMAND(X) \ + if (devices[i]->drv->drv_id == DRIVER_##X) \ count++; -#endif -#ifdef USE_BFLSC - if (devices[i]->drv->drv_id == DRIVER_bflsc) - count++; -#endif -#ifdef USE_BITFURY - if (devices[i]->drv->drv_id == DRIVER_bitfury) - count++; -#endif + ASIC_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND if (count == (ascid + 1)) goto foundit; } @@ -1270,29 +1256,18 @@ foundit: #endif #ifdef HAVE_AN_FPGA -static int numpgas() +static int numpgas(void) { int count = 0; int i; rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_BITFORCE - if (devices[i]->drv->drv_id == DRIVER_bitforce) - count++; -#endif -#ifdef USE_ICARUS - if (devices[i]->drv->drv_id == DRIVER_icarus) - count++; -#endif -#ifdef USE_ZTEX - if (devices[i]->drv->drv_id == DRIVER_ztex) - count++; -#endif -#ifdef USE_MODMINER - if (devices[i]->drv->drv_id == DRIVER_modminer) +#define DRIVER_ADD_COMMAND(X) \ + if (devices[i]->drv->drv_id == DRIVER_##X) \ count++; -#endif + FPGA_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND } rd_unlock(&devices_lock); return count; @@ -1305,22 +1280,11 @@ static int pgadevice(int pgaid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#ifdef USE_BITFORCE - if (devices[i]->drv->drv_id == DRIVER_bitforce) +#define DRIVER_ADD_COMMAND(X) \ + if (devices[i]->drv->drv_id == DRIVER_##X) \ count++; -#endif -#ifdef USE_ICARUS - if (devices[i]->drv->drv_id == DRIVER_icarus) - count++; -#endif -#ifdef USE_ZTEX - if (devices[i]->drv->drv_id == DRIVER_ztex) - count++; -#endif -#ifdef USE_MODMINER - if (devices[i]->drv->drv_id == DRIVER_modminer) - count++; -#endif + FPGA_PARSE_COMMANDS +#undef DRIVER_ADD_COMMAND if (count == (pgaid + 1)) goto foundit; } From 303a763162e50823b942d9affb23472c28674c21 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 13:08:15 +1000 Subject: [PATCH 78/88] Deuglify use of usb parse commands macro in usbutils. --- usbutils.c | 4 +--- usbutils.h | 9 +++++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/usbutils.c b/usbutils.c index c428b042..eae597f2 100644 --- a/usbutils.c +++ b/usbutils.c @@ -521,12 +521,10 @@ static int next_stat = USB_NOSTAT; #endif // DO_USB_STATS /* Create usb_commands array from USB_PARSE_COMMANDS macro in usbutils.h */ -#define USB_ADD_COMMAND(X, Y) Y, char *usb_commands[] = { - USB_PARSE_COMMANDS + USB_PARSE_COMMANDS(JUMPTABLE) "Null" }; -#undef USB_ADD_COMMAND #ifdef EOL #undef EOL diff --git a/usbutils.h b/usbutils.h index 9f93c2a5..f086441d 100644 --- a/usbutils.h +++ b/usbutils.h @@ -261,7 +261,10 @@ struct cg_usb_info { struct cg_usb_tmo usb_tmo[USB_TMOS]; }; -#define USB_PARSE_COMMANDS \ +#define ENUMERATION(a,b) a, +#define JUMPTABLE(a,b) b, + +#define USB_PARSE_COMMANDS(USB_ADD_COMMAND) \ USB_ADD_COMMAND(C_REJECTED, "RejectedNoDevice") \ USB_ADD_COMMAND(C_PING, "Ping") \ USB_ADD_COMMAND(C_CLEAR, "Clear") \ @@ -339,12 +342,10 @@ struct cg_usb_info { USB_ADD_COMMAND(C_BF1_IDENTIFY, "BF1Identify") /* Create usb_cmds enum from USB_PARSE_COMMANDS macro */ -#define USB_ADD_COMMAND(X, Y) X, enum usb_cmds { - USB_PARSE_COMMANDS + USB_PARSE_COMMANDS(ENUMERATION) C_MAX }; -#undef USB_ADD_COMMAND struct device_drv; struct cgpu_info; From 5e1ebd5070241963130c9e7cd2502b17e6422d2e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 13:54:16 +1000 Subject: [PATCH 79/88] Deuglify use of _PARSE_COMMANDS macro expansions. --- api.c | 27 +++++++-------------------- cgminer.c | 17 ++++++++--------- miner.h | 21 ++++++++++----------- usbutils.c | 20 +++++++++----------- 4 files changed, 34 insertions(+), 51 deletions(-) diff --git a/api.c b/api.c index 75c1c4f1..c70446df 100644 --- a/api.c +++ b/api.c @@ -1211,6 +1211,9 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson return root; } +#define DRIVER_COUNT_DRV(X) if (devices[i]->drv->drv_id == DRIVER_##X) \ + count++; + #ifdef HAVE_AN_ASIC static int numascs(void) { @@ -1219,11 +1222,7 @@ static int numascs(void) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#define DRIVER_ADD_COMMAND(X) \ - if (devices[i]->drv->drv_id == DRIVER_##X) \ - count++; - ASIC_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + ASIC_PARSE_COMMANDS(DRIVER_COUNT_DRV) } rd_unlock(&devices_lock); return count; @@ -1236,11 +1235,7 @@ static int ascdevice(int ascid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#define DRIVER_ADD_COMMAND(X) \ - if (devices[i]->drv->drv_id == DRIVER_##X) \ - count++; - ASIC_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + ASIC_PARSE_COMMANDS(DRIVER_COUNT_DRV) if (count == (ascid + 1)) goto foundit; } @@ -1263,11 +1258,7 @@ static int numpgas(void) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#define DRIVER_ADD_COMMAND(X) \ - if (devices[i]->drv->drv_id == DRIVER_##X) \ - count++; - FPGA_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + FPGA_PARSE_COMMANDS(DRIVER_COUNT_DRV) } rd_unlock(&devices_lock); return count; @@ -1280,11 +1271,7 @@ static int pgadevice(int pgaid) rd_lock(&devices_lock); for (i = 0; i < total_devices; i++) { -#define DRIVER_ADD_COMMAND(X) \ - if (devices[i]->drv->drv_id == DRIVER_##X) \ - count++; - FPGA_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + FPGA_PARSE_COMMANDS(DRIVER_COUNT_DRV) if (count == (pgaid + 1)) goto foundit; } diff --git a/cgminer.c b/cgminer.c index 19f2a0d1..337722a7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -7604,6 +7604,8 @@ static void hotplug_process() switch_logsize(true); } +#define DRIVER_DRV_DETECT_HOTPLUG(X) X##_drv.drv_detect(true); + static void *hotplug_thread(void __maybe_unused *userdata) { pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); @@ -7625,9 +7627,7 @@ static void *hotplug_thread(void __maybe_unused *userdata) /* Use the DRIVER_PARSE_COMMANDS macro to detect all * devices */ -#define DRIVER_ADD_COMMAND(X) X##_drv.drv_detect(true); - DRIVER_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + DRIVER_PARSE_COMMANDS(DRIVER_DRV_DETECT_HOTPLUG) if (new_devices) hotplug_process(); @@ -7653,6 +7653,9 @@ static void probe_pools(void) } } +#define DRIVER_FILL_DEVICE_DRV(X) fill_device_drv(&X##_drv); +#define DRIVER_DRV_DETECT_ALL(X) X##_drv.drv_detect(false); + int main(int argc, char *argv[]) { struct sigaction handler; @@ -7834,17 +7837,13 @@ int main(int argc, char *argv[]) #endif /* Use the DRIVER_PARSE_COMMANDS macro to fill all the device_drvs */ -#define DRIVER_ADD_COMMAND(X) fill_device_drv(&X##_drv); - DRIVER_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + DRIVER_PARSE_COMMANDS(DRIVER_FILL_DEVICE_DRV) if (opt_scrypt) opencl_drv.drv_detect(false); else { /* Use the DRIVER_PARSE_COMMANDS macro to detect all devices */ -#define DRIVER_ADD_COMMAND(X) X##_drv.drv_detect(false); - DRIVER_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + DRIVER_PARSE_COMMANDS(DRIVER_DRV_DETECT_ALL) } if (opt_display_devs) { diff --git a/miner.h b/miner.h index 42f97437..d945740e 100644 --- a/miner.h +++ b/miner.h @@ -234,34 +234,33 @@ static inline int fsync (int fd) * trying to claim same chip but different devices. Adding a device here will * update all macros in the code that use the *_PARSE_COMMANDS macros for each * listed driver. */ -#define FPGA_PARSE_COMMANDS \ +#define FPGA_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ DRIVER_ADD_COMMAND(bitforce) \ DRIVER_ADD_COMMAND(icarus) \ DRIVER_ADD_COMMAND(modminer) \ DRIVER_ADD_COMMAND(ztex) -#define ASIC_PARSE_COMMANDS \ +#define ASIC_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ DRIVER_ADD_COMMAND(bflsc) \ DRIVER_ADD_COMMAND(bitfury) \ DRIVER_ADD_COMMAND(avalon) -#define DRIVER_PARSE_COMMANDS \ +#define DRIVER_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ DRIVER_ADD_COMMAND(opencl) \ - FPGA_PARSE_COMMANDS \ - ASIC_PARSE_COMMANDS + FPGA_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ + ASIC_PARSE_COMMANDS(DRIVER_ADD_COMMAND) + +#define DRIVER_ENUM(X) DRIVER_##X, +#define DRIVER_PROTOTYPE(X) struct device_drv X##_drv; /* Create drv_driver enum from DRIVER_PARSE_COMMANDS macro */ -#define DRIVER_ADD_COMMAND(X) DRIVER_##X, enum drv_driver { - DRIVER_PARSE_COMMANDS + DRIVER_PARSE_COMMANDS(DRIVER_ENUM) DRIVER_MAX }; -#undef DRIVER_ADD_COMMAND /* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */ -#define DRIVER_ADD_COMMAND(X) struct device_drv X##_drv; -DRIVER_PARSE_COMMANDS; -#undef DRIVER_ADD_COMMAND +DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE) enum alive { LIFE_WELL, diff --git a/usbutils.c b/usbutils.c index eae597f2..e333b59e 100644 --- a/usbutils.c +++ b/usbutils.c @@ -1840,6 +1840,9 @@ static struct usb_find_devices *usb_check_each(int drvnum, struct device_drv *dr return NULL; } +#define DRIVER_USB_CHECK_EACH(X) if (drv->drv_id == DRIVER_##X) \ + return usb_check_each(DRIVER_##X, drv, dev); + static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, __maybe_unused struct libusb_device *dev) { if (drv_count[drv->drv_id].count >= drv_count[drv->drv_id].limit) { @@ -1849,11 +1852,7 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, return NULL; } -#define DRIVER_ADD_COMMAND(X) \ - if (drv->drv_id == DRIVER_##X) \ - return usb_check_each(DRIVER_##X, drv, dev); - DRIVER_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + DRIVER_PARSE_COMMANDS(DRIVER_USB_CHECK_EACH) return NULL; } @@ -3125,6 +3124,10 @@ void usb_cleanup() cgsem_destroy(&usb_resource_sem); } +#define DRIVER_COUNT_FOUND(X) if (strcasecmp(ptr, X##_drv.name) == 0) { \ + drv_count[X##_drv.drv_id].limit = lim; \ + found = true; \ + } void usb_initialise() { char *fre, *ptr, *comma, *colon; @@ -3210,12 +3213,7 @@ void usb_initialise() found = false; /* Use the DRIVER_PARSE_COMMANDS macro to iterate * over all the drivers. */ -#define DRIVER_ADD_COMMAND(X) if (strcasecmp(ptr, X##_drv.name) == 0) { \ - drv_count[X##_drv.drv_id].limit = lim; \ - found = true; \ - } - DRIVER_PARSE_COMMANDS -#undef DRIVER_ADD_COMMAND + DRIVER_PARSE_COMMANDS(DRIVER_COUNT_FOUND) if (!found) quit(1, "Invalid --usb DRV:limit - unknown DRV='%s'", ptr); From 5683a1144eb2f647800e2b505aaabd4e6edfa155 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 15:14:06 +1000 Subject: [PATCH 80/88] Provide a function to downgrade a cglock from a write lock to an intermediate variant. --- miner.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/miner.h b/miner.h index d945740e..60eb7516 100644 --- a/miner.h +++ b/miner.h @@ -843,7 +843,7 @@ static inline void cglock_init(cglock_t *lock) rwlock_init(&lock->rwlock); } -/* Read lock variant of cglock */ +/* Read lock variant of cglock. Cannot be promoted. */ static inline void cg_rlock(cglock_t *lock) { mutex_lock(&lock->mutex); @@ -851,7 +851,8 @@ static inline void cg_rlock(cglock_t *lock) mutex_unlock_noyield(&lock->mutex); } -/* Intermediate variant of cglock */ +/* Intermediate variant of cglock - behaves as a read lock but can be promoted + * to a write lock or demoted to read lock. */ static inline void cg_ilock(cglock_t *lock) { mutex_lock(&lock->mutex); @@ -878,6 +879,12 @@ static inline void cg_dwlock(cglock_t *lock) mutex_unlock_noyield(&lock->mutex); } +/* Demote a write variant to an intermediate variant */ +static inline void cg_dwilock(cglock_t *lock) +{ + wr_unlock(&lock->rwlock); +} + /* Downgrade intermediate variant to a read lock */ static inline void cg_dlock(cglock_t *lock) { From 01e3c878cf1d1ada966c692dd28621da89f02930 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 15:16:25 +1000 Subject: [PATCH 81/88] We should only yield once in cg_wunlock --- miner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner.h b/miner.h index 60eb7516..fdfc7797 100644 --- a/miner.h +++ b/miner.h @@ -899,7 +899,7 @@ static inline void cg_runlock(cglock_t *lock) static inline void cg_wunlock(cglock_t *lock) { - wr_unlock(&lock->rwlock); + wr_unlock_noyield(&lock->rwlock); mutex_unlock(&lock->mutex); } From ef62b281970e00c321872498b3eccf60e2926a81 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 29 Sep 2013 17:14:10 +1000 Subject: [PATCH 82/88] Icarus - CMR shouldn't wait the full timeout due to handle sharing --- driver-icarus.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index a42988bb..9ad4e43a 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -74,6 +74,7 @@ ASSERT1(sizeof(uint32_t) == 4); // USB ms timeout to wait - user specified timeouts are multiples of this #define ICARUS_WAIT_TIMEOUT 100 +#define ICARUS_CMR2_TIMEOUT 1 // Defined in multiples of ICARUS_WAIT_TIMEOUT // Must of course be greater than ICARUS_READ_COUNT_TIMING/ICARUS_WAIT_TIMEOUT @@ -186,6 +187,8 @@ struct ICARUS_INFO { struct ICARUS_HISTORY history[INFO_HISTORY+1]; uint32_t min_data_count; + int timeout; + // seconds per Hash double Hs; // ms til we abort @@ -434,7 +437,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct struct ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data); struct timeval read_start, read_finish; int err, amt; - int rc = 0; + int rc = 0, delay; int read_amount = ICARUS_READ_SIZE; bool first = true; @@ -446,7 +449,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct cgtime(&read_start); err = usb_read_ii_timeout(icarus, info->intinfo, (char *)buf, read_amount, &amt, - ICARUS_WAIT_TIMEOUT, C_GETRESULTS); + info->timeout, C_GETRESULTS); cgtime(&read_finish); if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) { applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)", @@ -483,6 +486,21 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct read_amount -= amt; first = false; } + + if (info->timeout < ICARUS_WAIT_TIMEOUT) { + delay = ICARUS_WAIT_TIMEOUT - rc; + if (delay > 0) { + cgsleep_ms(delay); + + if (thr && thr->work_restart) { + if (opt_debug) { + applog(LOG_DEBUG, + "Icarus Read: Work restart at %d ms", rc); + } + return ICA_NONCE_RESTART; + } + } + } } } @@ -796,6 +814,7 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices int baud, uninitialised_var(work_division), uninitialised_var(fpga_count); struct cgpu_info *icarus; int ret, err, amount, tries; + enum sub_ident ident; bool ok; icarus = usb_alloc_cgpu(&icarus_drv, 1); @@ -814,6 +833,23 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices quit(1, "Failed to malloc ICARUS_INFO"); icarus->device_data = (void *)info; + ident = usb_ident(icarus); + switch (ident) { + case IDENT_ICA: + case IDENT_BLT: + case IDENT_LLT: + case IDENT_AMU: + case IDENT_CMR1: + info->timeout = ICARUS_WAIT_TIMEOUT; + break; + case IDENT_CMR2: + info->timeout = ICARUS_CMR2_TIMEOUT; + break; + default: + quit(1, "%s icarus_detect_one() invalid %s ident=%d", + icarus->drv->dname, icarus->drv->dname, ident); + } + tries = 2; ok = false; while (!ok && tries-- > 0) { From c7fb4aad787911e3e2b9b57df6b7551a2e9c4305 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 29 Sep 2013 17:21:32 +1000 Subject: [PATCH 83/88] Icarus remove unneeded opt_debug tests due to applog being a macro --- driver-icarus.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 9ad4e43a..6ac1a0bf 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -474,10 +474,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct } if (thr && thr->work_restart) { - if (opt_debug) { - applog(LOG_DEBUG, - "Icarus Read: Work restart at %d ms", rc); - } + applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc); return ICA_NONCE_RESTART; } @@ -493,10 +490,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct cgsleep_ms(delay); if (thr && thr->work_restart) { - if (opt_debug) { - applog(LOG_DEBUG, - "Icarus Read: Work restart at %d ms", rc); - } + applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc); return ICA_NONCE_RESTART; } } @@ -1055,12 +1049,10 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work, if (unlikely(estimate_hashes > 0xffffffff)) estimate_hashes = 0xffffffff; - if (opt_debug) { - applog(LOG_DEBUG, "%s%d: no nonce = 0x%08lX hashes (%ld.%06lds)", - icarus->drv->name, icarus->device_id, - (long unsigned int)estimate_hashes, - elapsed.tv_sec, elapsed.tv_usec); - } + applog(LOG_DEBUG, "%s%d: no nonce = 0x%08lX hashes (%ld.%06lds)", + icarus->drv->name, icarus->device_id, + (long unsigned int)estimate_hashes, + elapsed.tv_sec, elapsed.tv_usec); return estimate_hashes; } @@ -1092,12 +1084,10 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work, if (opt_debug || info->do_icarus_timing) timersub(&tv_finish, &tv_start, &elapsed); - if (opt_debug) { - applog(LOG_DEBUG, "%s%d: nonce = 0x%08x = 0x%08lX hashes (%ld.%06lds)", - icarus->drv->name, icarus->device_id, - nonce, (long unsigned int)hash_count, - elapsed.tv_sec, elapsed.tv_usec); - } + applog(LOG_DEBUG, "%s%d: nonce = 0x%08x = 0x%08lX hashes (%ld.%06lds)", + icarus->drv->name, icarus->device_id, + nonce, (long unsigned int)hash_count, + elapsed.tv_sec, elapsed.tv_usec); // Ignore possible end condition values ... and hw errors // TODO: set limitations on calculated values depending on the device From ff90e6ae837e0253eb7971f5cf6ed30506dba313 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 17:44:41 +1000 Subject: [PATCH 84/88] usbinfo.devlock is only ever write locked so convert it to a mutex --- usbutils.c | 10 +++++----- usbutils.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/usbutils.c b/usbutils.c index e333b59e..35c8865e 100644 --- a/usbutils.c +++ b/usbutils.c @@ -34,11 +34,11 @@ */ #define DEVLOCK(cgpu, _pth_state) do { \ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &_pth_state); \ - wr_lock(cgpu->usbinfo.devlock); \ + mutex_lock(cgpu->usbinfo.devlock); \ } while (0) #define DEVUNLOCK(cgpu, _pth_state) do { \ - wr_unlock(cgpu->usbinfo.devlock); \ + mutex_unlock(cgpu->usbinfo.devlock); \ pthread_setcancelstate(_pth_state, NULL); \ } while (0) @@ -1384,7 +1384,7 @@ struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads) if (unlikely(!cgpu->usbinfo.devlock)) quit(1, "Failed to calloc devlock for %s in usb_alloc_cgpu", drv->dname); - rwlock_init(cgpu->usbinfo.devlock); + mutex_init(cgpu->usbinfo.devlock); return cgpu; } @@ -3083,9 +3083,9 @@ void usb_cleanup() case DRIVER_modminer: case DRIVER_icarus: case DRIVER_avalon: - wr_lock(cgpu->usbinfo.devlock); + mutex_lock(cgpu->usbinfo.devlock); release_cgpu(cgpu); - wr_unlock(cgpu->usbinfo.devlock); + mutex_unlock(cgpu->usbinfo.devlock); count++; break; default: diff --git a/usbutils.h b/usbutils.h index f086441d..8274c76b 100644 --- a/usbutils.h +++ b/usbutils.h @@ -237,7 +237,7 @@ struct cg_usb_info { * that uses the lock - however, all usbutils code MUST use it * to avoid devices disappearing while in use by multiple threads */ - pthread_rwlock_t *devlock; + pthread_mutex_t *devlock; time_t last_pipe; uint64_t pipe_count; From 14887ba852e559ffd518ffaf6d19422aa80ad044 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 17:44:41 +1000 Subject: [PATCH 85/88] usbinfo.devlock is only ever write locked so convert it to a mutex --- usbutils.c | 10 +++++----- usbutils.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/usbutils.c b/usbutils.c index e333b59e..35c8865e 100644 --- a/usbutils.c +++ b/usbutils.c @@ -34,11 +34,11 @@ */ #define DEVLOCK(cgpu, _pth_state) do { \ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &_pth_state); \ - wr_lock(cgpu->usbinfo.devlock); \ + mutex_lock(cgpu->usbinfo.devlock); \ } while (0) #define DEVUNLOCK(cgpu, _pth_state) do { \ - wr_unlock(cgpu->usbinfo.devlock); \ + mutex_unlock(cgpu->usbinfo.devlock); \ pthread_setcancelstate(_pth_state, NULL); \ } while (0) @@ -1384,7 +1384,7 @@ struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads) if (unlikely(!cgpu->usbinfo.devlock)) quit(1, "Failed to calloc devlock for %s in usb_alloc_cgpu", drv->dname); - rwlock_init(cgpu->usbinfo.devlock); + mutex_init(cgpu->usbinfo.devlock); return cgpu; } @@ -3083,9 +3083,9 @@ void usb_cleanup() case DRIVER_modminer: case DRIVER_icarus: case DRIVER_avalon: - wr_lock(cgpu->usbinfo.devlock); + mutex_lock(cgpu->usbinfo.devlock); release_cgpu(cgpu); - wr_unlock(cgpu->usbinfo.devlock); + mutex_unlock(cgpu->usbinfo.devlock); count++; break; default: diff --git a/usbutils.h b/usbutils.h index f086441d..8274c76b 100644 --- a/usbutils.h +++ b/usbutils.h @@ -237,7 +237,7 @@ struct cg_usb_info { * that uses the lock - however, all usbutils code MUST use it * to avoid devices disappearing while in use by multiple threads */ - pthread_rwlock_t *devlock; + pthread_mutex_t *devlock; time_t last_pipe; uint64_t pipe_count; From 0a5599844f492f15040729e6ddf69a497b54ffce Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 23:44:45 +1000 Subject: [PATCH 86/88] Add magic init sequence required on BF1 devices to get them mining on windows. --- driver-bitfury.c | 9 +++++++++ usbutils.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/driver-bitfury.c b/driver-bitfury.c index 6bb4e8c3..8069a1d2 100644 --- a/driver-bitfury.c +++ b/driver-bitfury.c @@ -28,7 +28,16 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury) static void bitfury_open(struct cgpu_info *bitfury) { + uint32_t buf[2]; + bitfury_empty_buffer(bitfury); + /* Magic sequence to reset device only really needed for windows but + * harmless on linux. */ + buf[0] = 0x80250000; + buf[1] = 0x00000800; + usb_transfer(bitfury, 0, 9, 1, 0, C_BF1_RESET); + usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_OPEN); + usb_transfer_data(bitfury, 0x21, 0x20, 0x0000, 0, buf, 7, C_BF1_INIT); } static void bitfury_close(struct cgpu_info *bitfury) diff --git a/usbutils.h b/usbutils.h index 8274c76b..457381d0 100644 --- a/usbutils.h +++ b/usbutils.h @@ -328,7 +328,9 @@ struct cg_usb_info { USB_ADD_COMMAND(C_ENABLE_UART, "EnableUART") \ USB_ADD_COMMAND(C_BB_SET_VOLTAGE, "SetCoreVoltage") \ USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") \ + USB_ADD_COMMAND(C_BF1_RESET, "BF1Reset") \ USB_ADD_COMMAND(C_BF1_OPEN, "BF1Open") \ + USB_ADD_COMMAND(C_BF1_INIT, "BF1Init") \ USB_ADD_COMMAND(C_BF1_CLOSE, "BF1Close") \ USB_ADD_COMMAND(C_BF1_REQINFO, "BF1RequestInfo") \ USB_ADD_COMMAND(C_BF1_GETINFO, "BF1GetInfo") \ From 03dd347fce6fb49946080cb3bca63383c16b02ad Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 23:51:04 +1000 Subject: [PATCH 87/88] Update NEWS. --- NEWS | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/NEWS b/NEWS index 5c7d6976..ad190119 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,140 @@ +Version 3.5.0 - 29th September 2013 + +- Add magic init sequence required on BF1 devices to get them mining on windows. +- usbinfo.devlock is only ever write locked so convert it to a mutex +- Icarus remove unneeded opt_debug tests due to applog being a macro +- Icarus - CMR shouldn't wait the full timeout due to handle sharing +- We should only yield once in cg_wunlock +- Provide a function to downgrade a cglock from a write lock to an intermediate +variant. +- Deuglify use of _PARSE_COMMANDS macro expansions. +- Deuglify use of usb parse commands macro in usbutils. +- Use the driver add commands macros in api.c to avoid individually listing +them. +- Separate out asic fpga and opencl drivers in the driver parse commands macro +for use individually as needed. +- Use macro expansion in usb_find_devices to avoid explicitly listing them all. +- Use macro expansion to iterate over all the drivers without explicitly writing +them out in usbutils.c +- Iterate over the bitfury offsets in order of decreasing likelihood. +- Reattach the kernel driver on linux on usb_uninit. +- Attach the kernel driver on failure to usb init on linux. +- libusb kernel driver operations are only available on linux. +- There is no need to get the external prototypes for drivers in cgminer.c any +more. +- Remove unnecessary gpu_threads initialisation. +- Put avalon last in the sequence of adding drivers to prevent it trying to +claim similar chip devices on startup. +- Use macro expansion to iterate over all device drivers without needing to +explicitly code in support in all places. Pass a hotplug bool to the detect() +function to prevent opencl trying to hogplug GPUs. +- Forward declare all device drivers in miner.h avoiding the need to export them +everywhere else. +- Add a noop function for driver detect when it's missing. +- Reuse the DRIVER_ macros to avoid having yet another definition for DRV_ +- Use macro expansion to generate extern device_drv prototypes. +- Create a macro list of drivers to enable easier addition of further drivers. +- There is no point setting the BF1 preferred packet size to the maximum since +it will do so automatically. +- icarus ensure all cmr interfaces are initialised properly +- usbutils - fix USBDEBUG warnings +- Remove unnecessary steps in communicating with BF1 and just use USB interface +1. +- usbutils - usb_bulk_transfer fix the buf/data fix +- usb_bulk_transfer - use the allocated buffer +- Set preferred packet sizes per interface on BF1. +- usbutils allow PrefPacketSize per endpoint +- Remove magic control sequences on open/close on BF1 and just flush the read +buffers. +- Check return codes in getinfo and reset and fail as needed in BF1. +- Check return code for bitfury_open and release resources properly on failed +initialisation. +- Abstract out flushing of interrupt reads in BF1 devices. +- Perform interrupt read after close message on BF1 as per serial close. +- Perform interrupt read flush as per serial open on BF1 devices. +- Add information for 2nd USB interface on BF1 devices and choose interface 1 +for bulk transfers. +- usbutils - bulk transfer copy test fix +- usbutils - add USBDEBUG for usb_bulk_transfer +- Add more read_ii variants to usbutils. +- Name remainder of BFU usb commands used. +- Use submit_tested_work in bitfury driver to avoid unnecessarily re-testing the +work for validity. +- Abstract out work submission once it's been tested, to be used by drivers that +do their own internal validity testing. +- Store the hash2 array in struct work for further reuse. +- usbutils - which_intinfo not requried +- Use the test_nonce function within submit_nonce and store the uint32 +corresponding to hash2 37 for further use. +- usbutils - interfaces must all be on one handle - ep implies the interface +- avalon stats use exact type +- Only set share diff if we've confirmed it's a share first. +- Update ASIC-README for bitfury devices. +- Use an array of offsets when checking nonces in bitfury_checkresults +- Limit the duration we wait for reads in BF1 based on time already elapsed to +account for other delays such as work restart messages or out of work. +- Minimise size of serial string we copy in BF1 stats to avoid overflow. +- Implement basic API stats for BF1 and increase array of results to check for +the rare straggling result. +- Space debug output for bf1 to separate from numerals. +- Abstract out the bitfury open close and reset functions and use them on +reinit. +- Rename BF1 devices BF1 +- Check for work restart, breaking out early after usb reads in BF1. +- Do not lose the first sets of results from BF1. +- There is no point checking for results from the next round of work on BF1. +- Last result returned by BF1 is an end of results marker so ignore it. +- restart_wait should return 0 if thr_restart is true. +- Remove unused code by bitfury driver since current driver uses serialised +scanhash. +- Meter out return of estimated hashes in BF1 to smooth out visible hashrate. +- Optimise inner scanhash loop for bf1. +- Add yet another backup work for triple buffering of work in bf1 to account for +extra late results returned and don't check nonce offsets which appear to never +return. +- Name the work request and result usb commands for BF1 +- Define a mandatory upper limit to waiting for reset and data on BF1 based on +full nonce duration. +- Decrease usb buffering to verbose logging. +- Add in first draft for a serialised work model sending/receiving data for BF1 +devices. +- Add complete close sequence to bf1 as it happens on serial. +- Provide a bitfury identify function for bf1. +- Reliably extract BF1 information at startup and reset the device. +- Add commands for getting BF1 bitfury info +- Add magic BF1 bitfury open and close control sequences. +- Add BF1 detection code to bitfury driver. +- Create basic placeholders for bitfury driver code. +- Add bf1 device information to usbutils to enable device detection. +- Add basic defines for building for bitfury devices. +- Add redfury device to udev rules. +- avalon: display the FPGA controller version on API +- pool_active uninitialised_var rolltime +- Use macro expansion to only need to define usb enums and commands in one +place. +- usbutils saving incorrect overflow buffer +- ignore libusb.la and *.lo on linux +- icarus support CMR with no extensions +- usbtils - interfaces dont work yet in libusb windows so disable for that only +- Provide a --disable-libcurl config option to build support for stratum mining +only. +- Fix the api-example.c compile under Linux +- usbutils - only release the device once - for the first intinfo +- usbutils set_interface is no longer valid +- ubsutils interfaces much each have their own handle +- usbutils kernel_detach should use the interface number +- usbutils - allow the driver to change which_intinfo +- Reset quotas on load balance for all pools at the same time to avoid running +out during selection and unintentionally dropping to fallback. +- Break out of select pool from a common point for appropriate debug messages +and to avoid further tests. +- usbutils correct/reverse CMR product numbers +- usbutils specifically track handles and interfaces +- change drivers to use usb_interface() - required for multi interface change +- usbutils - allow a device to use multiple interfaces (and better var names) +- Cast -1 to (char) to cope with different default char types on ARM. + + Version 3.4.3 - 13th September 2013 - Put corefoundation and iokit separate in ldflags for darwin. From d1c95832c6b83e168cfb6a96946943fd5e053eaa Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 29 Sep 2013 23:51:46 +1000 Subject: [PATCH 88/88] Bump version to 3.5.0 --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 24e68729..95795bc5 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## m4_define([v_maj], [3]) -m4_define([v_min], [4]) -m4_define([v_mic], [3]) +m4_define([v_min], [5]) +m4_define([v_mic], [0]) ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## m4_define([v_ver], [v_maj.v_min.v_mic]) m4_define([lt_rev], m4_eval(v_maj + v_min))