Commit c1ff90a7ab9c19e58df1ed6bd67a87e6e6a19421

Con Kolivas 2013-04-18T15:07:32

Do testing for HW errors on submit nonce for both scrypt and sha.

diff --git a/cgminer.c b/cgminer.c
index cbbb510..cf1c03a 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -5525,7 +5525,8 @@ void inc_hw_errors(struct thr_info *thr)
 	thr->cgpu->drv->hw_error(thr);
 }
 
-static bool hashtest(struct thr_info *thr, struct work *work)
+/* Returns 1 if meets difficulty target, 0 if not, -1 if hw error */
+static int hashtest(struct thr_info *thr, struct work *work)
 {
 	uint32_t *data32 = (uint32_t *)(work->data);
 	unsigned char swap[80];
@@ -5533,7 +5534,6 @@ static bool hashtest(struct thr_info *thr, struct work *work)
 	unsigned char hash1[32];
 	unsigned char hash2[32];
 	uint32_t *hash2_32 = (uint32_t *)hash2;
-	bool ret = false;
 
 	flip80(swap32, data32);
 	sha2(swap, 80, hash1);
@@ -5544,29 +5544,29 @@ static bool hashtest(struct thr_info *thr, struct work *work)
 		applog(LOG_WARNING, "%s%d: invalid nonce - HW error",
 				thr->cgpu->drv->name, thr->cgpu->device_id);
 
-		inc_hw_errors(thr);
-		goto out;
+		return -1;
 	}
 
 	mutex_lock(&stats_lock);
 	thr->cgpu->last_device_valid_work = time(NULL);
 	mutex_unlock(&stats_lock);
 
-	ret = fulltest(hash2, work->target);
-	if (!ret) {
+	if (!fulltest(hash2, work->target)) {
 		applog(LOG_INFO, "Share below target");
 		/* Check the diff of the share, even if it didn't reach the
 		 * target, just to set the best share value if it's higher. */
 		share_diff(work);
+		return 0;
 	}
-out:
-	return ret;
+
+	return 1;
 }
 
 void 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;
+	int valid;
 
 	gettimeofday(&tv_work_found, NULL);
 	*work_nonce = htole32(nonce);
@@ -5578,10 +5578,15 @@ void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 	mutex_unlock(&stats_lock);
 
 	/* Do one last check before attempting to submit the work */
-	if (!opt_scrypt && !hashtest(thr, work))
-		return;
+	if (opt_scrypt)
+		valid = scrypt_test(work->data, work->target, nonce);
+	else
+		valid = hashtest(thr, work);
 
-	submit_work_async(work, &tv_work_found);
+	if (unlikely(valid == -1))
+		inc_hw_errors(thr);
+	else if (valid == 1)
+		submit_work_async(work, &tv_work_found);
 }
 
 static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes)
diff --git a/findnonce.c b/findnonce.c
index 65055d9..2f9d27a 100644
--- a/findnonce.c
+++ b/findnonce.c
@@ -179,17 +179,6 @@ struct pc_data {
 	int found;
 };
 
-static void send_scrypt_nonce(struct pc_data *pcd, uint32_t nonce)
-{
-	struct thr_info *thr = pcd->thr;
-	struct work *work = pcd->work;
-
-	if (scrypt_test(work->data, work->target, nonce))
-		submit_nonce(thr, work, nonce);
-	else
-		inc_hw_errors(thr);
-}
-
 static void *postcalc_hash(void *userdata)
 {
 	struct pc_data *pcd = (struct pc_data *)userdata;
@@ -212,10 +201,7 @@ static void *postcalc_hash(void *userdata)
 		uint32_t nonce = pcd->res[entry];
 
 		applog(LOG_DEBUG, "OCL NONCE %u found in slot %d", nonce, entry);
-		if (opt_scrypt)
-			send_scrypt_nonce(pcd, nonce);
-		else
-			submit_nonce(thr, pcd->work, nonce);
+		submit_nonce(thr, pcd->work, nonce);
 	}
 
 	discard_work(pcd->work);
diff --git a/scrypt.c b/scrypt.c
index e0af4f0..3d92c15 100644
--- a/scrypt.c
+++ b/scrypt.c
@@ -420,7 +420,7 @@ void scrypt_regenhash(struct work *work)
 }
 
 /* Used externally as confirmation of correct OCL code */
-bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
+int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
 {
 	uint32_t tmp_hash7, Htarg = ((const uint32_t *)ptarget)[7];
 	uint32_t data[20], ohash[8];
@@ -432,7 +432,11 @@ bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t no
 	scrypt_1024_1_1_256_sp(data, scratchbuf, ohash);
 	tmp_hash7 = be32toh(ohash[7]);
 
-	return (tmp_hash7 <= Htarg);
+	/* FIXME: Needs to be able to return 0 as well for not meeting target
+	 * but target diff currently is sent to devices. */
+	if (tmp_hash7 > Htarg)
+		return -1;
+	return 1;
 }
 
 bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate,
diff --git a/scrypt.h b/scrypt.h
index c7b8538..8f3d219 100644
--- a/scrypt.h
+++ b/scrypt.h
@@ -4,16 +4,16 @@
 #include "miner.h"
 
 #ifdef USE_SCRYPT
-extern bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget,
+extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget,
 			uint32_t nonce);
 extern void scrypt_regenhash(struct work *work);
 
 #else /* USE_SCRYPT */
-static inline bool scrypt_test(__maybe_unused unsigned char *pdata,
+static inline int scrypt_test(__maybe_unused unsigned char *pdata,
 			       __maybe_unused const unsigned char *ptarget,
 			       __maybe_unused uint32_t nonce)
 {
-	return false;
+	return 0;
 }
 
 static inline void scrypt_regenhash(__maybe_unused struct work *work)