Browse Source

icarus: Abstract nonce processing

Luke Dashjr 12 years ago
parent
commit
27eaf89832
1 changed files with 28 additions and 9 deletions
  1. 28 9
      driver-icarus.c

+ 28 - 9
driver-icarus.c

@@ -805,6 +805,15 @@ static bool icarus_job_start(struct thr_info *thr)
 	return true;
 }
 
+static
+struct work *icarus_process_worknonce(struct icarus_state *state, uint32_t *nonce)
+{
+	*nonce = be32toh(*nonce);
+	if (test_nonce(state->last_work, *nonce, false))
+		return state->last_work;
+	return NULL;
+}
+
 static
 void handle_identify(struct thr_info * const thr, int ret, const bool was_first_run)
 {
@@ -879,12 +888,13 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 
 	struct ICARUS_INFO *info;
 
-	uint32_t nonce = 0;
+	uint32_t nonce;
+	struct work *nonce_work;
 	int64_t hash_count;
 	struct timeval tv_start, elapsed;
 	struct timeval tv_history_start, tv_history_finish;
 	double Ti, Xi;
-	int curr_hw_errors, i;
+	int i;
 	bool was_hw_error;
 	bool was_first_run;
 
@@ -956,16 +966,18 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	tcflush(fd, TCOFLUSH);
 #endif
 
-	nonce = be32toh(nonce);
-
 	// Handle dynamic clocking for "subclass" devices
 	// This needs to run before sending next job, since it hashes the command too
 	if (info->dclk.freqM && likely(ret == ICA_GETS_OK || ret == ICA_GETS_TIMEOUT)) {
 		int qsec = ((4 * elapsed.tv_sec) + (elapsed.tv_usec / 250000)) ?: 1;
 		for (int n = qsec; n; --n)
 			dclk_gotNonces(&info->dclk);
-		if (nonce && !test_nonce(state->last_work, nonce, false))
-			dclk_errorCount(&info->dclk, qsec);
+		if (ret == ICA_GETS_OK)
+		{
+			nonce_work = icarus_process_worknonce(state, &nonce);
+			if (!nonce_work)
+				dclk_errorCount(&info->dclk, qsec);
+		}
 	}
 
 	if (unlikely(state->identify))
@@ -1015,9 +1027,16 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 		goto out;
 	}
 
-	curr_hw_errors = icarus->hw_errors;
-	submit_nonce(thr, state->last_work, nonce);
-	was_hw_error = (curr_hw_errors > icarus->hw_errors);
+	// Only ICA_GETS_OK gets here
+	
+	if (!info->dclk.freqM)
+		nonce_work = icarus_process_worknonce(state, &nonce);
+	
+	was_hw_error = (!nonce_work);
+	if (likely(!was_hw_error))
+		submit_nonce(thr, nonce_work, nonce);
+	else
+		inc_hw_errors(thr, state->last_work, nonce);
 	icarus_transition_work(state, work);
 
 	// Force a USB close/reopen on any hw error