diff --git a/README b/README index fac8e6f8..862ec544 100644 --- a/README +++ b/README @@ -199,6 +199,8 @@ FPGA mining boards(BitForce, Icarus, ModMiner, Ztex) only options: --scan-serial|-S Serial port to probe for FPGA mining device + This option is only for BitForce, Icarus, and/or ModMiner FPGAs + By default, cgminer will scan for autodetected FPGAs unless at least one -S is specified for that driver. If you specify -S and still want cgminer to scan, you must also use "-S auto". If you want to prevent cgminer from @@ -210,6 +212,11 @@ FPGA mining boards(BitForce, Icarus, ModMiner, Ztex) only options: On windows is usually of the format \\.\COMn (where n = the correct device number for the FPGA device) + The official supplied binaries are compiled with support for all FPGAs. + To force the code to only attempt detection with a specific driver, + prepend the argument with the driver name followed by a colon. + For example, "icarus:/dev/ttyUSB0" or "bitforce:\\.\COM5" + For other FPGA details see the FPGA-README diff --git a/cgminer.c b/cgminer.c index 0fec0aa6..ec062789 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3829,6 +3829,8 @@ void *miner_thread(void *userdata) const time_t request_interval = opt_scantime * 2 / 3 ? : 1; unsigned const long request_nonce = MAXTHREADS / 3 * 2; bool requested = false; + const bool primary = (!mythr->device_thread) || mythr->primary_thread; + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); gettimeofday(&getwork_start, NULL); @@ -3910,7 +3912,7 @@ void *miner_thread(void *userdata) * starting of every next thread to try and get * all devices busy before worrying about * getting work for their extra threads */ - if (mythr->device_thread) { + if (!primary) { struct timespec rgtp; rgtp.tv_sec = 0; diff --git a/driver-bitforce.c b/driver-bitforce.c index 5e9d2582..20904596 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -55,6 +55,8 @@ static bool bitforce_detect_one(const char *devpath) char *s; char pdevbuf[0x100]; + applog(LOG_DEBUG, "BFL: Attempting to open %s", devpath); + int fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { applog(LOG_ERR, "BFL: Failed to open %s", devpath); @@ -101,7 +103,7 @@ static char bitforce_detect_auto() static void bitforce_detect() { - serial_detect_auto("bitforce", bitforce_detect_one, bitforce_detect_auto); + serial_detect_auto(bitforce_api.dname, bitforce_detect_one, bitforce_detect_auto); } static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce) diff --git a/driver-icarus.c b/driver-icarus.c index ee9800c4..a463c281 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -379,6 +379,8 @@ static bool icarus_detect_one(const char *devpath) unsigned char ob_bin[64], nonce_bin[ICARUS_READ_SIZE]; char *nonce_hex; + applog(LOG_DEBUG, "Icarus Detect: Attempting to open %s", devpath); + fd = icarus_open2(devpath, true); if (unlikely(fd == -1)) { applog(LOG_ERR, "Icarus Detect: Failed to open %s", devpath); @@ -444,7 +446,7 @@ static bool icarus_detect_one(const char *devpath) static void icarus_detect() { - serial_detect("icarus", icarus_detect_one); + serial_detect(icarus_api.dname, icarus_detect_one); } static bool icarus_prepare(struct thr_info *thr) diff --git a/driver-modminer.c b/driver-modminer.c index 0afce2d1..2f8ee111 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -103,7 +103,7 @@ modminer_detect_auto() static void modminer_detect() { - serial_detect_auto("modminer", modminer_detect_one, modminer_detect_auto); + serial_detect_auto(modminer_api.dname, modminer_detect_one, modminer_detect_auto); } #define bailout(...) return _bailout(-1, modminer, __VA_ARGS__); @@ -318,6 +318,8 @@ modminer_fpga_init(struct thr_info *thr) mutex_unlock(&modminer->device_mutex); + thr->primary_thread = true; + return true; } diff --git a/fpgautils.c b/fpgautils.c index 783015aa..70387c69 100644 --- a/fpgautils.c +++ b/fpgautils.c @@ -119,20 +119,25 @@ serial_autodetect_devserial(detectone_func_t detectone, const char*prodname) } char -_serial_detect(const char*dnamec, size_t dnamel, detectone_func_t detectone, autoscan_func_t autoscan, bool forceauto) +_serial_detect(const char*dname, detectone_func_t detectone, autoscan_func_t autoscan, bool forceauto) { if (total_devices == MAX_DEVICES) return 0; struct string_elist *iter, *tmp; - const char*s; + const char*s, *p; bool inhibitauto = false; char found = 0; + size_t dnamel = strlen(dname); list_for_each_entry_safe(iter, tmp, &scan_devices, list) { s = iter->string; - if (!strncmp(dnamec, iter->string, dnamel)) - s += dnamel; + if ((p = strchr(s, ':')) && p[1] != '\0') { + size_t plen = p - s; + if (plen != dnamel || strncasecmp(s, dname, plen)) + continue; + s = p + 1; + } if (!strcmp(s, "auto")) forceauto = true; else diff --git a/fpgautils.h b/fpgautils.h index 91ccb30a..c45183b7 100644 --- a/fpgautils.h +++ b/fpgautils.h @@ -16,13 +16,13 @@ typedef bool(*detectone_func_t)(const char*); typedef char(*autoscan_func_t)(); -extern char _serial_detect(const char*dnamec, size_t dnamel, detectone_func_t, autoscan_func_t, bool force_autoscan); +extern char _serial_detect(const char*dname, detectone_func_t, autoscan_func_t, bool force_autoscan); #define serial_detect_fauto(dname, detectone, autoscan) \ - _serial_detect(dname ":", sizeof(dname), detectone, autoscan, true) + _serial_detect(dname, detectone, autoscan, true) #define serial_detect_auto(dname, detectone, autoscan) \ - _serial_detect(dname ":", sizeof(dname), detectone, autoscan, false) + _serial_detect(dname, detectone, autoscan, false) #define serial_detect(dname, detectone) \ - _serial_detect(dname ":", sizeof(dname), detectone, NULL, false) + _serial_detect(dname, detectone, NULL, false) extern char serial_autodetect_devserial(detectone_func_t, const char*prodname); extern char serial_autodetect_udev (detectone_func_t, const char*prodname); diff --git a/miner.h b/miner.h index 098d4bc5..5259d358 100644 --- a/miner.h +++ b/miner.h @@ -397,6 +397,7 @@ struct thread_q { struct thr_info { int id; int device_thread; + bool primary_thread; pthread_t pth; struct thread_q *q;