diff --git a/API-README b/API-README index c73bb2aa..6f5fbe12 100644 --- a/API-README +++ b/API-README @@ -80,7 +80,7 @@ The STATUS section is: This defaults to the cgminer version but is the value of --api-description if it was specified at runtime. -For API version 1.9: +For API version 1.10 and later: The list of requests - a (*) means it requires privileged access - and replies are: @@ -290,6 +290,8 @@ API V1.12 Modified API commands: 'stats' - more pool stats added +Support for the ModMinerQuad FPGA was added + ---------- API V1.11 (cgminer v2.4.2) diff --git a/api.c b/api.c index f18f7f73..d8ddde3e 100644 --- a/api.c +++ b/api.c @@ -27,6 +27,10 @@ #include "miner.h" #include "driver-cpu.h" /* for algo_names[], TODO: re-factor dependency */ +#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) || defined(USE_MODMINER) +#define HAVE_AN_FPGA 1 +#endif + #if defined(unix) || defined(__APPLE__) #include #include @@ -188,6 +192,9 @@ static const char *DEVICECODE = "" #ifdef USE_ZTEX "ZTX " #endif +#ifdef USE_MODMINER + "MMQ " +#endif #ifdef WANT_CPUMINE "CPU " #endif @@ -220,7 +227,7 @@ static const char *OSINFO = #define _MINECON "CONFIG" #define _GPU "GPU" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA #define _PGA "PGA" #endif @@ -253,7 +260,7 @@ static const char ISJSON = '{'; #define JSON_MINECON JSON1 _MINECON JSON2 #define JSON_GPU JSON1 _GPU JSON2 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA #define JSON_PGA JSON1 _PGA JSON2 #endif @@ -335,7 +342,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_TOOMANYP 54 #define MSG_ADDPOOL 55 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA #define MSG_PGANON 56 #define MSG_PGADEV 57 #define MSG_INVPGA 58 @@ -344,7 +351,7 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_NUMPGA 59 #define MSG_NOTIFY 60 -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA #define MSG_PGALRENA 61 #define MSG_PGALRDIS 62 #define MSG_PGAENA 63 @@ -402,7 +409,7 @@ struct CODES { { SEVERITY_ERR, MSG_NOPOOL, PARAM_NONE, "No pools" }, { SEVERITY_SUCC, MSG_DEVS, PARAM_DMAX, "%d GPU(s)" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA " - %d PGA(s)" #endif #ifdef WANT_CPUMINE @@ -411,7 +418,7 @@ struct CODES { }, { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs" -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA "/PGAs" #endif #ifdef WANT_CPUMINE @@ -425,7 +432,7 @@ struct CODES { { SEVERITY_ERR, MSG_INVCMD, PARAM_NONE, "Invalid command" }, { SEVERITY_ERR, MSG_MISID, PARAM_NONE, "Missing device id parameter" }, { SEVERITY_SUCC, MSG_GPUDEV, PARAM_GPU, "GPU%d" }, -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA { SEVERITY_ERR, MSG_PGANON, PARAM_NONE, "No PGAs" }, { SEVERITY_SUCC, MSG_PGADEV, PARAM_PGA, "PGA%d" }, { SEVERITY_ERR, MSG_INVPGA, PARAM_PGAMAX, "Invalid PGA id %d - range is 0 - %d" }, @@ -519,6 +526,10 @@ extern struct device_api icarus_api; extern struct device_api ztex_api; #endif +#ifdef USE_MODMINER +extern struct device_api modminer_api; +#endif + // This is only called when expected to be needed (rarely) // i.e. strings outside of the codes control (input from the user) static char *escape_string(char *str, bool isjson) @@ -581,7 +592,7 @@ static char *escape_string(char *str, bool isjson) return buf; } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA static int numpgas() { int count = 0; @@ -599,6 +610,10 @@ static int numpgas() #ifdef USE_ZTEX if (devices[i]->api == &ztex_api) count++; +#endif +#ifdef USE_MODMINER + if (devices[i]->api == &modminer_api) + count++; #endif } return count; @@ -621,6 +636,10 @@ static int pgadevice(int pgaid) #ifdef USE_ZTEX if (devices[i]->api == &ztex_api) count++; +#endif +#ifdef USE_MODMINER + if (devices[i]->api == &modminer_api) + count++; #endif if (count == (pgaid + 1)) return i; @@ -636,7 +655,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) { char severity; char *ptr; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA int pga; #endif #ifdef WANT_CPUMINE @@ -681,7 +700,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) case PARAM_GPUMAX: sprintf(ptr, codes[i].description, paramid, nDevs - 1); break; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA case PARAM_PGAMAX: pga = numpgas(); sprintf(ptr, codes[i].description, paramid, pga - 1); @@ -703,7 +722,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) sprintf(ptr, codes[i].description, paramid, total_pools - 1); break; case PARAM_DMAX: -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA pga = numpgas(); #endif #ifdef WANT_CPUMINE @@ -714,7 +733,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson) #endif sprintf(ptr, codes[i].description, nDevs -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA , pga #endif #ifdef WANT_CPUMINE @@ -784,7 +803,7 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, const char *adl = NO; #endif -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA pgacount = numpgas(); #endif @@ -856,7 +875,7 @@ static void gpustatus(int gpu, bool isjson) } } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA static void pgastatus(int pga, bool isjson) { char buf[TMPBUFSIZ]; @@ -871,11 +890,35 @@ static void pgastatus(int pga, bool isjson) struct cgpu_info *cgpu = devices[dev]; double frequency = 0; + float temp = cgpu->temp; #ifdef USE_ZTEX if (cgpu->api == &ztex_api && cgpu->device_ztex) frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1); #endif +#ifdef USE_MODMINER +// TODO: a modminer has up to 4 devices but only 1 set of data for all ... +// except 4 sets of data for temp/clock +// So this should change in the future to just find the single temp/clock +// if the modminer code splits the device into seperate devices later +// For now, just display the highest temp and the average clock + if (cgpu->api == &modminer_api) { + int tc = cgpu->threads; + int i; + + temp = 0; + if (tc > 4) + tc = 4; + for (i = 0; i < tc; i++) { + struct thr_info *thr = cgpu->thr[i]; + struct modminer_fpga_state *state = thr->cgpu_data; + if (state->temp > temp) + temp = state->temp; + frequency += state->clock; + } + frequency /= (tc ? tc : 1); + } +#endif cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; @@ -897,7 +940,7 @@ static void pgastatus(int pga, bool isjson) ? "{\"PGA\":%d,\"Name\":\"%s\",\"ID\":%d,\"Enabled\":\"%s\",\"Status\":\"%s\",\"Temperature\":%.2f,\"MHS av\":%.2f,\"MHS %ds\":%.2f,\"Accepted\":%d,\"Rejected\":%d,\"Hardware Errors\":%d,\"Utility\":%.2f,\"Last Share Pool\":%d,\"Last Share Time\":%lu,\"Total MH\":%.4f,\"Frequency\":%.2f}" : "PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f,Frequency=%.2f" SEPSTR, pga, cgpu->api->name, cgpu->device_id, - enabled, status, cgpu->temp, + enabled, status, temp, cgpu->total_mhashes / total_secs, opt_log_interval, cgpu->rolling, cgpu->accepted, cgpu->rejected, cgpu->hw_errors, cgpu->utility, ((unsigned long)(cgpu->last_share_pool_time) > 0) ? cgpu->last_share_pool : -1, @@ -939,7 +982,7 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b int numpga = 0; int i; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA numpga = numpgas(); #endif @@ -964,7 +1007,7 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b devcount++; } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA if (numpga > 0) for (i = 0; i < numpga; i++) { if (isjson && devcount > 0) @@ -1025,7 +1068,7 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) strcat(io_buffer, JSON_CLOSE); } -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA static void pgadev(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { int numpga = numpgas(); @@ -1420,7 +1463,7 @@ static void pgacount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo char buf[TMPBUFSIZ]; int count = 0; -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA count = numpgas(); #endif @@ -2105,7 +2148,7 @@ struct CMDS { { "gpudisable", gpudisable, true }, { "gpurestart", gpurestart, true }, { "gpu", gpudev, false }, -#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) +#ifdef HAVE_AN_FPGA { "pga", pgadev, false }, { "pgaenable", pgaenable, true }, { "pgadisable", pgadisable, true }, diff --git a/driver-modminer.c b/driver-modminer.c index d139091e..0afce2d1 100644 --- a/driver-modminer.c +++ b/driver-modminer.c @@ -232,22 +232,6 @@ modminer_device_prepare(struct cgpu_info *modminer) #undef bailout -struct modminer_fpga_state { - bool work_running; - struct work running_work; - struct timeval tv_workstart; - uint32_t hashes; - - char next_work_cmd[46]; - - unsigned char clock; - int no_nonce_counter; - int good_share_counter; - time_t last_cutoff_reduced; - - unsigned char temp; -}; - static bool modminer_fpga_prepare(struct thr_info *thr) { diff --git a/fpgautils.h b/fpgautils.h index 7b8b3317..91ccb30a 100644 --- a/fpgautils.h +++ b/fpgautils.h @@ -18,11 +18,11 @@ typedef char(*autoscan_func_t)(); extern char _serial_detect(const char*dnamec, size_t dnamel, detectone_func_t, autoscan_func_t, bool force_autoscan); #define serial_detect_fauto(dname, detectone, autoscan) \ - _serial_detect(dname ":", sizeof(dname)+1, detectone, autoscan, true) + _serial_detect(dname ":", sizeof(dname), detectone, autoscan, true) #define serial_detect_auto(dname, detectone, autoscan) \ - _serial_detect(dname ":", sizeof(dname)+1, detectone, autoscan, false) + _serial_detect(dname ":", sizeof(dname), detectone, autoscan, false) #define serial_detect(dname, detectone) \ - _serial_detect(dname ":", sizeof(dname)+1, detectone, NULL, false) + _serial_detect(dname ":", sizeof(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 83d84117..69cdcf24 100644 --- a/miner.h +++ b/miner.h @@ -745,6 +745,24 @@ struct work { time_t share_found_time; }; +#ifdef USE_MODMINER +struct modminer_fpga_state { + bool work_running; + struct work running_work; + struct timeval tv_workstart; + uint32_t hashes; + + char next_work_cmd[46]; + + unsigned char clock; + int no_nonce_counter; + int good_share_counter; + time_t last_cutoff_reduced; + + unsigned char temp; +}; +#endif + extern void get_datestamp(char *, struct timeval *); extern bool test_nonce(struct work *work, uint32_t nonce); bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);