Commit 820d662c9d4afb4824abecb42e0be31b06533f77

Paul Sheppard 2012-06-10T23:11:59

Removed idle mode. Added watchdog thread BFL temperature monitoring.

diff --git a/api.c b/api.c
index 3e6501a..268d90a 100644
--- a/api.c
+++ b/api.c
@@ -167,7 +167,6 @@ static const char *SICK = "Sick";
 static const char *NOSTART = "NoStart";
 static const char *DISABLED = "Disabled";
 static const char *ALIVE = "Alive";
-static const char *IDLE = "Idle";
 static const char *REJECTING = "Rejecting";
 static const char *UNKNOWN = "Unknown";
 #define _DYNAMIC "D"
@@ -466,7 +465,7 @@ struct CODES {
  { SEVERITY_SUCC,  MSG_GPUFAN,	PARAM_BOTH,	"Setting GPU %d fan to (%s) reported succeess" },
  { SEVERITY_ERR,   MSG_MISFN,	PARAM_NONE,	"Missing save filename parameter" },
  { SEVERITY_ERR,   MSG_BADFN,	PARAM_STR,	"Can't open or create save file '%s'" },
- { SEVERITY_SUCC,  MSG_SAVED,	PARAM_STR,	"Configuration saved to file '%s'" },
+ { SEVERITY_ERR,   MSG_SAVED,	PARAM_STR,	"Configuration saved to file '%s'" },
  { SEVERITY_ERR,   MSG_ACCDENY,	PARAM_STR,	"Access denied to '%s' command" },
  { SEVERITY_SUCC,  MSG_ACCOK,	PARAM_NONE,	"Privileged access OK" },
  { SEVERITY_SUCC,  MSG_ENAPOOL,	PARAM_POOL,	"Enabling pool %d:'%s'" },
@@ -880,7 +879,7 @@ static void pgastatus(int pga, bool isjson)
 
 		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
 
-		if (cgpu->deven == DEV_ENABLED)
+		if (cgpu->deven != DEV_DISABLED)
 			enabled = (char *)YES;
 		else
 			enabled = (char *)NO;
@@ -891,8 +890,6 @@ static void pgastatus(int pga, bool isjson)
 			status = (char *)SICK;
 		else if (cgpu->status == LIFE_NOSTART)
 			status = (char *)NOSTART;
-		else if (cgpu->deven == DEV_IDLE)
-			status = (char *)IDLE;
 		else
 			status = (char *)ALIVE;
 
@@ -1095,7 +1092,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
 
 	struct cgpu_info *cgpu = devices[dev];
 
-	if (cgpu->deven == DEV_ENABLED) {
+	if (cgpu->deven != DEV_DISABLED) {
 		strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson));
 		return;
 	}
@@ -1146,12 +1143,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
 
 	struct cgpu_info *cgpu = devices[dev];
 
-	if (cgpu->deven != DEV_ENABLED) {
+	if (cgpu->deven == DEV_DISABLED) {
 		strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson));
 		return;
 	}
 
-	cgpu->deven = DEV_IDLE;
+	cgpu->deven = DEV_DISABLED;
 
 	strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson));
 }
@@ -1982,13 +1979,12 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, 
 
 void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
 {
-	char filename[PATH_MAX];
 	FILE *fcfg;
 	char *ptr;
 
 	if (param == NULL || *param == '\0') {
-		default_save_file(filename);
-		param = filename;
+		strcpy(io_buffer, message(MSG_MISFN, 0, NULL, isjson));
+		return;
 	}
 
 	fcfg = fopen(param, "w");
@@ -2570,3 +2566,4 @@ die:
 
 	mutex_unlock(&quit_restart_lock);
 }
+
diff --git a/cgminer.c b/cgminer.c
index ad1259e..77284cd 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -3918,7 +3918,7 @@ void *miner_thread(void *userdata)
 				tv_lastupdate = tv_end;
 			}
 
-			if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) {
+			if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) {
 				applog(LOG_WARNING, "Thread %d being disabled", thr_id);
 disabled:
 				mythr->rolling = mythr->cgpu->rolling = 0;
@@ -4274,13 +4274,17 @@ static void *watchdog_thread(void __maybe_unused *userdata)
 			}
 		}
 
-#ifdef HAVE_OPENCL
 		for (i = 0; i < total_devices; ++i) {
 			struct cgpu_info *cgpu = devices[i];
 			struct thr_info *thr = cgpu->thread;
 			enum dev_enable *denable;
 			int gpu;
+			
+			if (cgpu->api->get_stats) {
+				cgpu->api->get_stats(cgpu);
+			}
 
+#ifdef HAVE_OPENCL
 			if (cgpu->api != &opencl_api)
 				continue;
 			/* Use only one thread per device to determine if the GPU is healthy */
@@ -4300,6 +4304,7 @@ static void *watchdog_thread(void __maybe_unused *userdata)
 					temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune);
 			}
 #endif
+			
 			/* Thread is waiting on getwork or disabled */
 			if (thr->getwork || *denable == DEV_DISABLED)
 				continue;
@@ -4347,8 +4352,9 @@ static void *watchdog_thread(void __maybe_unused *userdata)
 				if (opt_restart)
 					reinit_device(thr->cgpu);
 			}
+#endif /* HAVE_OPENCL */
 		}
-#endif
+
 	}
 
 	return NULL;
diff --git a/driver-bitforce.c b/driver-bitforce.c
index 00eeb9c..e930d14 100644
--- a/driver-bitforce.c
+++ b/driver-bitforce.c
@@ -133,6 +133,8 @@ static bool bitforce_detect_one(const char *devpath)
 		s[0] = '\0';
 		bitforce->name = strdup(pdevbuf + 7);
 	}
+	
+	mutex_init(&bitforce->dev_lock);
 
 	return add_cgpu(bitforce);
 }
@@ -284,8 +286,11 @@ static bool bitforce_init(struct cgpu_info *bitforce)
 
 	bitforce->device_fd = fdDev;
 
+	mutex_lock(&bitforce->dev_lock);
 	BFwrite(fdDev, "ZGX", 3);
 	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
+	mutex_unlock(&bitforce->dev_lock);
+	
 	if (unlikely(!pdevbuf[0])) {
 		applog(LOG_ERR, "Error reading from BitForce (ZGX)");
 		return false;
@@ -311,8 +316,11 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
 	char pdevbuf[0x100];
 	char *s;
 
+	mutex_lock(&bitforce->dev_lock);
 	BFwrite(fdDev, "ZLX", 3);
 	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
+	mutex_unlock(&bitforce->dev_lock);
+	
 	if (unlikely(!pdevbuf[0])) {
 		applog(LOG_ERR, "Error reading temp from BitForce (ZLX)");
 		return false;
@@ -322,8 +330,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
 		if (temp > 0) {
 			bitforce->temp = temp;
 			if (temp > bitforce->cutofftemp) {
-				applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, setting idle", bitforce->api->name, bitforce->device_id);
-				bitforce->deven = DEV_IDLE;
+				applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id);
+				bitforce->deven = DEV_RECOVER;
 
 				bitforce->device_last_not_well = time(NULL);
 				bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF;
@@ -342,27 +350,30 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work)
 	unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>";
 	char *s;
 
+	mutex_lock(&bitforce->dev_lock);
 	BFwrite(fdDev, "ZDX", 3);
 	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
 	if (unlikely(!pdevbuf[0])) {
 		applog(LOG_ERR, "Error reading from BitForce (ZDX)");
+		mutex_unlock(&bitforce->dev_lock);
 		return false;
 	}
 	if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) {
 		applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf);
+		mutex_unlock(&bitforce->dev_lock);
 		return false;
 	}
-
 	memcpy(ob + 8, work->midstate, 32);
 	memcpy(ob + 8 + 32, work->data + 64, 12);
+
 	BFwrite(fdDev, ob, 60);
 	if (opt_debug) {
 		s = bin2hex(ob + 8, 44);
 		applog(LOG_DEBUG, "BitForce block data: %s", s);
 		free(s);
 	}
-
 	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
+	mutex_unlock(&bitforce->dev_lock);
 	if (unlikely(!pdevbuf[0])) {
 		applog(LOG_ERR, "Error reading from BitForce (block data)");
 		return false;
@@ -386,10 +397,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 
 	i = BITFORCE_SLEEP_MS;
 	while (i < BITFORCE_TIMEOUT_MS) {
+    	mutex_lock(&bitforce->dev_lock);
 		BFwrite(fdDev, "ZFX", 3);
 		BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
+	    mutex_unlock(&bitforce->dev_lock);
 		if (unlikely(!pdevbuf[0])) {
 			applog(LOG_ERR, "Error reading from BitForce (ZFX)");
+	    	mutex_unlock(&bitforce->dev_lock);
 			return 0;
 		}
 		if (pdevbuf[0] != 'B')
@@ -410,7 +424,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 	work->blk.nonce = 0xffffffff;
 	if (pdevbuf[2] == '-') 
 		return 0xffffffff;   /* No valid nonce found */
-	else if (pdevbuf[0] == 'I')
+	else if (pdevbuf[0] == 'I') 
 		return 1;          /* Device idle */
 	else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) {
 		applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf);
@@ -434,12 +448,25 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work)
 	return 0xffffffff;
 }
 
+static void bitforce_shutdown(struct thr_info *thr)
+{
+	struct cgpu_info *bitforce = thr->cgpu;
+	int fdDev = bitforce->device_fd;
+
+	BFclose(fdDev);
+}
+
 static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce)
 {
 	struct cgpu_info *bitforce = thr->cgpu;
 	bool dev_enabled = (bitforce->deven == DEV_ENABLED);
 	static enum dev_enable last_dev_state = DEV_ENABLED;
 	
+	if (bitforce->deven == DEV_DISABLED) {
+		bitforce_shutdown(thr);
+		return 1;
+	}
+	
 	// if device has just gone from disabled to enabled, re-initialise it
 	if (last_dev_state == DEV_DISABLED && dev_enabled)
 		bitforce_init(bitforce);
@@ -448,9 +475,6 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6
 		if (!bitforce_send_work(thr, work))
 			return 0;
 
-	if (!bitforce_get_temp(bitforce))
-		return 0;
-
 	usleep(BITFORCE_SLEEP_US);
 
 	if (dev_enabled)
@@ -459,12 +483,9 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6
 		return 1;
 }
 
-static void bitforce_shutdown(struct thr_info *thr)
+static bool bitforce_get_stats(struct cgpu_info *bitforce)
 {
-	struct cgpu_info *bitforce = thr->cgpu;
-	int fdDev = bitforce->device_fd;
-
-	BFclose(fdDev);
+	return bitforce_get_temp(bitforce);
 }
 
 struct device_api bitforce_api = {
@@ -472,6 +493,7 @@ struct device_api bitforce_api = {
 	.name = "BFL",
 	.api_detect = bitforce_detect,
 	.get_statline_before = get_bitforce_statline_before,
+	.get_stats = bitforce_get_stats,
 	.thread_prepare = bitforce_thread_prepare,
 	.scanhash = bitforce_scanhash,
 	.thread_shutdown = bitforce_shutdown
diff --git a/driver-icarus.c b/driver-icarus.c
index 630b66b..75ab5e3 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -566,12 +566,6 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	uint32_t values;
 	uint64_t hash_count_range;
 
-	/* Device developer can make use of idle state, until then, disable and return */
-	if (thr->cgpu->deven == DEV_IDLE) {
-		thr->cgpu->deven = DEV_DISABLED;
-		return 1;
-	}
-
 	elapsed.tv_sec = elapsed.tv_usec = 0;
 
 	icarus = thr->cgpu;
diff --git a/driver-ztex.c b/driver-ztex.c
index 91f7a7b..c881cd7 100644
--- a/driver-ztex.c
+++ b/driver-ztex.c
@@ -199,12 +199,6 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 	bool overflow, found, rv;
 	struct libztex_hash_data hdata[GOLDEN_BACKLOG];
 
-	/* Device developer can make use of idle state, until then, disable and return */
-	if (thr->cgpu->deven == DEV_IDLE) {
-		thr->cgpu->deven = DEV_DISABLED;
-		return 1;
-	}
-	
 	ztex = thr->cgpu->device_ztex;
 
 	memcpy(sendbuf, work->data + 64, 12);
diff --git a/miner.h b/miner.h
index f5f7122..2251031 100644
--- a/miner.h
+++ b/miner.h
@@ -235,6 +235,7 @@ struct device_api {
 	void (*get_statline_before)(char*, struct cgpu_info*);
 	void (*get_statline)(char*, struct cgpu_info*);
 	void (*get_api_stats)(char*, struct cgpu_info*, bool);
+	bool (*get_stats)(struct cgpu_info*);
 
 	// Thread-specific functions
 	bool (*thread_prepare)(struct thr_info*);
@@ -250,7 +251,6 @@ enum dev_enable {
 	DEV_ENABLED,
 	DEV_DISABLED,
 	DEV_RECOVER,
-	DEV_IDLE,
 };
 
 enum cl_kernels {
@@ -366,6 +366,8 @@ struct cgpu_info {
 	int dev_thermal_cutoff_count;
 
 	struct cgminer_stats cgminer_stats;
+	
+	pthread_mutex_t dev_lock;
 };
 
 extern bool add_cgpu(struct cgpu_info*);