Browse Source

Merge branch 'master' of git://github.com/ckolivas/cgminer.git

Paul Sheppard 13 years ago
parent
commit
bc4a259af7
10 changed files with 153 additions and 57 deletions
  1. 3 1
      API-README
  2. 1 1
      Makefile.am
  3. 31 0
      NEWS
  4. 63 20
      api.c
  5. 25 15
      cgminer.c
  6. 1 1
      configure.ac
  7. 0 16
      driver-modminer.c
  8. 3 3
      fpgautils.h
  9. 18 0
      miner.h
  10. 8 0
      miner.php

+ 3 - 1
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)

+ 1 - 1
Makefile.am

@@ -69,7 +69,7 @@ endif # HAS_YASM
 endif # HAS_CPUMINE
 
 if NEED_FPGAUTILS
-cgminer_SOURCES += fpgautils.c
+cgminer_SOURCES += fpgautils.c fpgautils.h
 endif
 
 if HAS_BITFORCE

+ 31 - 0
NEWS

@@ -1,3 +1,34 @@
+Version 2.4.3 - June 14, 2012
+
+- can_roll and should_roll should have no bearing on the cycle period within the miner_thread so remove it.
+- Check for strategy being changed to load balance when enabling LPs.
+- Check that all threads on the device that called get_work are waiting on getwork before considering the pool lagging.
+- Iterate over each thread belonging to each device in the hashmeter instead of searching for them now that they're a list.
+- When using rotate pool strategy, ensure we only select from alive enabled pools.
+- Start longpoll from every pool when load balance strategy is in use.
+- Add mandatory and block fields to the work struct. Flag any shares that are detected as blocks as mandatory to submit, along with longpoll work from a previously rejecting pool.
+- Consider the fan optimal if fanspeed is dropping but within the optimal speed window.
+- Fix typo in some API messages (succeess/success)
+- api.c MMQ stat bugs
+- Bugfix: Fix warnings when built without libudev support
+- Bugfix: slay a variety of warnings
+- Bugfix: modminer: Fix unsigned/signed comparison and similar warnings
+- API add ModMinerQuad support
+- Bugfix: Honour forceauto parameter in serial_detect functions
+- modminer: Temperature sensor improvements
+- modminer: Make log messages more consistent in format
+- Only adjust GPU speed up if the fanspeed is within the normal fanrange and hasn't been turned to maximum speed under overheat conditions.
+- ModMiner use valid .name
+- New driver: BTCFPGA ModMiner
+- Abstract generally useful FPGA code into fpgautils.c
+- API add stats for pool getworks
+- miner.php option to hide specific fields from the display
+- miner.php add version numbers to the summary page
+- Update debian configs to v2.4.2
+- Add API and FPGA READMEs into Makefile to be included in source distribution.
+- Icarus - fix unit64_t printf warnings
+
+
 Version 2.4.2 - June 2, 2012
 
 - API.class compiled with Java SE 6.0_03 - works with Win7x64

+ 63 - 20
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 <errno.h>
 	#include <sys/socket.h>
@@ -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 },

+ 25 - 15
cgminer.c

@@ -3302,12 +3302,9 @@ static void hashmeter(int thr_id, struct timeval *diff,
 
 		/* Rolling average for each thread and each device */
 		decay_time(&thr->rolling, local_mhashes / secs);
-		for (i = 0; i < mining_threads; i++) {
-			struct thr_info *th = &thr_info[i];
+		for (i = 0; i < cgpu->threads; i++)
+			thread_rolling += cgpu->thr[i]->rolling;
 
-			if (th->cgpu == cgpu)
-				thread_rolling += th->rolling;
-		}
 		mutex_lock(&hash_lock);
 		decay_time(&cgpu->rolling, thread_rolling);
 		cgpu->total_mhashes += local_mhashes;
@@ -3635,11 +3632,26 @@ retry:
 		goto out;
 	}
 
-	if (requested && !newreq && !requests_staged() && requests_queued() >= mining_threads &&
-	    !pool_tset(pool, &pool->lagging)) {
-		applog(LOG_WARNING, "Pool %d not providing work fast enough", pool->pool_no);
-		pool->getfail_occasions++;
-		total_go++;
+	if (!pool->lagging && requested && !newreq && !requests_staged() && requests_queued() >= mining_threads) {
+		struct cgpu_info *cgpu = thr->cgpu;
+		bool stalled = true;
+		int i;
+
+		/* Check to see if all the threads on the device that called
+		 * get_work are waiting on work and only consider the pool
+		 * lagging if true */
+		for (i = 0; i < cgpu->threads; i++) {
+			if (!cgpu->thr[i]->getwork) {
+				stalled = false;
+				break;
+			}
+		}
+
+		if (stalled && !pool_tset(pool, &pool->lagging)) {
+			applog(LOG_WARNING, "Pool %d not providing work fast enough", pool->pool_no);
+			pool->getfail_occasions++;
+			total_go++;
+		}
 	}
 
 	newreq = requested = false;
@@ -3802,8 +3814,7 @@ void *miner_thread(void *userdata)
 	struct timeval getwork_start;
 
 	/* Try to cycle approximately 5 times before each log update */
-	const unsigned long def_cycle = opt_log_interval / 5 ? : 1;
-	long cycle;
+	const long cycle = opt_log_interval / 5 ? : 1;
 	struct timeval tv_start, tv_end, tv_workstart, tv_lastupdate;
 	struct timeval diff, sdiff, wdiff;
 	uint32_t max_nonce = api->can_limit_work ? api->can_limit_work(mythr) : 0xffffffff;
@@ -3842,7 +3853,6 @@ void *miner_thread(void *userdata)
 			break;
 		}
 		requested = false;
-		cycle = (can_roll(work) && should_roll(work)) ? 1 : def_cycle;
 		gettimeofday(&tv_workstart, NULL);
 		work->blk.nonce = 0;
 		cgpu->max_hashes = 0;
@@ -3947,7 +3957,7 @@ void *miner_thread(void *userdata)
 				}
 			}
 
-			if (unlikely(sdiff.tv_sec < cycle)) {
+			if (unlikely((long)sdiff.tv_sec < cycle)) {
 				if (likely(!api->can_limit_work || max_nonce == 0xffffffff))
 					continue;
 
@@ -4088,7 +4098,7 @@ static void wait_lpcurrent(struct pool *pool)
 	if (pool->enabled == POOL_REJECTING || pool_strategy == POOL_LOADBALANCE)
 		return;
 
-	while (pool != current_pool()) {
+	while (pool != current_pool() && pool_strategy != POOL_LOADBALANCE) {
 		mutex_lock(&lp_lock);
 		pthread_cond_wait(&lp_cond, &lp_lock);
 		mutex_unlock(&lp_lock);

+ 1 - 1
configure.ac

@@ -2,7 +2,7 @@
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 m4_define([v_maj], [2])
 m4_define([v_min], [4])
-m4_define([v_mic], [2])
+m4_define([v_mic], [3])
 ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
 m4_define([v_ver], [v_maj.v_min.v_mic])
 m4_define([lt_rev], m4_eval(v_maj + v_min))

+ 0 - 16
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)
 {

+ 3 - 3
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);
 

+ 18 - 0
miner.h

@@ -751,6 +751,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);

+ 8 - 0
miner.php

@@ -60,6 +60,14 @@ $warnfont = '<font color=red><b>';
 $warnoff = '</b></font>';
 $dfmt = 'H:i:s j-M-Y \U\T\CP';
 #
+# This below allows you to put your own settings into a seperate file
+# so you don't need to update miner.php with your preferred settings
+# every time a new version is released
+# Just create the file 'myminer.php' in the same directory as
+# 'miner.php' - and put your own settings in there
+if (file_exists('myminer.php'))
+ include_once('myminer.php');
+#
 # Ensure it is only ever shown once
 global $showndate;
 $showndate = false;