Browse Source

more work on hashrate and read_count

Xiangfu 13 years ago
parent
commit
bbaf70cde0
2 changed files with 61 additions and 61 deletions
  1. 60 59
      driver-avalon.c
  2. 1 2
      driver-avalon.h

+ 60 - 59
driver-avalon.c

@@ -1,6 +1,5 @@
 /*
 /*
- * Copyright 2012 2013 Xiangfu <xiangfu@openmobilefree.com>
- * Copyright 2012 Andrew Smith
+ * Copyright 2013 Xiangfu
  *
  *
  * This program is free software; you can redistribute it and/or modify it
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
  * under the terms of the GNU General Public License as published by the Free
@@ -35,6 +34,7 @@
 #include "driver-avalon.h"
 #include "driver-avalon.h"
 #include "hexdump.c"
 #include "hexdump.c"
 
 
+static int no_matching_work = 0;
 static int option_offset = -1;
 static int option_offset = -1;
 
 
 struct avalon_info **avalon_info;
 struct avalon_info **avalon_info;
@@ -116,23 +116,32 @@ static int avalon_send_task(int fd, const struct avalon_task *at,
 	size_t nr_len;
 	size_t nr_len;
 	struct cgpu_info *avalon;
 	struct cgpu_info *avalon;
 	struct avalon_info *info;
 	struct avalon_info *info;
-	uint64_t delay = 32000000; /* default 32ms for B19200 */
+	uint64_t delay = 32000000; /* Default 32ms for B19200 */
 	uint32_t nonce_range;
 	uint32_t nonce_range;
 	int i;
 	int i;
 
 
-	nr_len = AVALON_WRITE_SIZE + 4 * at->asic_num;
+	if (at->nonce_elf)
+		nr_len = AVALON_WRITE_SIZE + 4 * at->asic_num;
+	else
+		nr_len = AVALON_WRITE_SIZE;
+
 	buf = calloc(1, AVALON_WRITE_SIZE + nr_len);
 	buf = calloc(1, AVALON_WRITE_SIZE + nr_len);
 	if (!buf)
 	if (!buf)
 		return AVA_SEND_ERROR;
 		return AVA_SEND_ERROR;
-
 	memcpy(buf, at, AVALON_WRITE_SIZE);
 	memcpy(buf, at, AVALON_WRITE_SIZE);
 
 
-	nonce_range = (uint32_t)0xffffffff / at->asic_num;
-	for (i = 0; i < at->asic_num; i++) {
-		buf[AVALON_WRITE_SIZE + (i * 4) + 3] = (i * nonce_range & 0xff000000) >> 24;
-		buf[AVALON_WRITE_SIZE + (i * 4) + 2] = (i * nonce_range & 0x00ff0000) >> 16;
-		buf[AVALON_WRITE_SIZE + (i * 4) + 1] = (i * nonce_range & 0x0000ff00) >> 8;
-		buf[AVALON_WRITE_SIZE + (i * 4) + 0] = (i * nonce_range & 0x000000ff) >> 0;
+	if (at->nonce_elf) {
+		nonce_range = (uint32_t)0xffffffff / at->asic_num;
+		for (i = 0; i < at->asic_num; i++) {
+			buf[AVALON_WRITE_SIZE + (i * 4) + 3] =
+				(i * nonce_range & 0xff000000) >> 24;
+			buf[AVALON_WRITE_SIZE + (i * 4) + 2] =
+				(i * nonce_range & 0x00ff0000) >> 16;
+			buf[AVALON_WRITE_SIZE + (i * 4) + 1] =
+				(i * nonce_range & 0x0000ff00) >> 8;
+			buf[AVALON_WRITE_SIZE + (i * 4) + 0] =
+				(i * nonce_range & 0x000000ff) >> 0;
+		}
 	}
 	}
 #if defined(__BIG_ENDIAN__) || defined(MIPSEB)
 #if defined(__BIG_ENDIAN__) || defined(MIPSEB)
 	uint8_t tt = 0;
 	uint8_t tt = 0;
@@ -311,7 +320,8 @@ static int avalon_reset(int fd, uint8_t timeout_p, uint8_t asic_num_p,
 	}
 	}
 
 
 	if (i != 11) {
 	if (i != 11) {
-		applog(LOG_ERR, "Avalon: Reset failed! not a Avalon? (%d: %02x %02x %02x %02x)",
+		applog(LOG_ERR, "Avalon: Reset failed! not a Avalon?"
+		       " (%d: %02x %02x %02x %02x)",
 		       i, buf[0], buf[1], buf[2], buf[3]);
 		       i, buf[0], buf[1], buf[2], buf[3]);
 		return 1;
 		return 1;
 	}
 	}
@@ -321,7 +331,8 @@ static int avalon_reset(int fd, uint8_t timeout_p, uint8_t asic_num_p,
 	nanosleep(&p, NULL);
 	nanosleep(&p, NULL);
 
 
 	applog(LOG_ERR,
 	applog(LOG_ERR,
-	       "Avalon: Fan1: %d, Fan2: %d, Fan3: %d. Temp1: %d, Temp2: %d, Temp3: %d",
+	       "Avalon: Fan1: %d, Fan2: %d, Fan3: %d\t"
+	       "Temp1: %d, Temp2: %d, Temp3: %d",
 	       ar->fan0, ar->fan1, ar->fan2, ar->temp0, ar->temp1, ar->temp2);
 	       ar->fan0, ar->fan1, ar->fan2, ar->temp0, ar->temp1, ar->temp2);
 
 
 	applog(LOG_ERR, "Avalon: Reset succeeded");
 	applog(LOG_ERR, "Avalon: Reset succeeded");
@@ -333,16 +344,18 @@ static void do_avalon_close(struct thr_info *thr)
 	struct cgpu_info *avalon = thr->cgpu;
 	struct cgpu_info *avalon = thr->cgpu;
 	avalon_close(avalon->device_fd);
 	avalon_close(avalon->device_fd);
 	avalon->device_fd = -1;
 	avalon->device_fd = -1;
-	/* FIXME: we should free the bulk0/1/2 */
+
+	no_matching_work = 0;
+	/* FIXME: should I free the bulk1 and bulk2? */
 }
 }
 
 
 static void set_timing_mode(struct cgpu_info *avalon, struct avalon_result *ar)
 static void set_timing_mode(struct cgpu_info *avalon, struct avalon_result *ar)
 {
 {
 	struct avalon_info *info = avalon_info[avalon->device_id];
 	struct avalon_info *info = avalon_info[avalon->device_id];
 
 
-	info->Hs = ((info->timeout * AVALON_HASH_TIME_FACTOR) / (double)0xffffffff);
-	info->read_count =
-		((int)(info->timeout * AVALON_HASH_TIME_FACTOR * TIME_FACTOR) - 1) / info->miner_count;
+	info->read_count = ((float)info->timeout * AVALON_HASH_TIME_FACTOR *
+			    TIME_FACTOR) / (float)info->miner_count;
+
 	info->fan0 = ar->fan0;
 	info->fan0 = ar->fan0;
 	info->fan1 = ar->fan1;
 	info->fan1 = ar->fan1;
 	info->fan2 = ar->fan2;
 	info->fan2 = ar->fan2;
@@ -616,14 +629,9 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **bulk_work,
 	int i, work_i0, work_i1, work_i2;
 	int i, work_i0, work_i1, work_i2;
 	int avalon_get_work_count;
 	int avalon_get_work_count;
 
 
+	struct timeval tv_start, tv_finish, elapsed;
 	uint32_t nonce;
 	uint32_t nonce;
 	int64_t hash_count;
 	int64_t hash_count;
-	struct timeval tv_start, tv_finish, elapsed;
-
-	int curr_hw_errors;
-	bool was_hw_error;
-
-	int64_t estimate_hashes;
 
 
 	avalon = thr->cgpu;
 	avalon = thr->cgpu;
 	info = avalon_info[avalon->device_id];
 	info = avalon_info[avalon->device_id];
@@ -680,15 +688,17 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **bulk_work,
 
 
 	elapsed.tv_sec = elapsed.tv_usec = 0;
 	elapsed.tv_sec = elapsed.tv_usec = 0;
 	gettimeofday(&tv_start, NULL);
 	gettimeofday(&tv_start, NULL);
+
 	hash_count = 0;
 	hash_count = 0;
 	while(true) {
 	while(true) {
+		work_i0 = work_i1 = work_i2 = -1;
+
 		full = avalon_buffer_full(fd);
 		full = avalon_buffer_full(fd);
 		applog(LOG_DEBUG, "Avalon: Buffer full: %s",
 		applog(LOG_DEBUG, "Avalon: Buffer full: %s",
 		       ((full == AVA_BUFFER_FULL) ? "Yes" : "No"));
 		       ((full == AVA_BUFFER_FULL) ? "Yes" : "No"));
 		if (full == AVA_BUFFER_EMPTY)
 		if (full == AVA_BUFFER_EMPTY)
 			break;
 			break;
 
 
-		work_i0 = work_i1 = work_i2 = -1;
 		ret = avalon_get_result(fd, &ar, thr, &tv_finish);
 		ret = avalon_get_result(fd, &ar, thr, &tv_finish);
 		if (ret == AVA_GETS_ERROR) {
 		if (ret == AVA_GETS_ERROR) {
 			avalon_free_work(thr, bulk0);
 			avalon_free_work(thr, bulk0);
@@ -700,26 +710,10 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **bulk_work,
 			dev_error(avalon, REASON_DEV_COMMS_ERROR);
 			dev_error(avalon, REASON_DEV_COMMS_ERROR);
 			return 0;
 			return 0;
 		}
 		}
-		/* aborted before becoming idle, get new work */
 		if (ret == AVA_GETS_TIMEOUT) {
 		if (ret == AVA_GETS_TIMEOUT) {
 			timersub(&tv_finish, &tv_start, &elapsed);
 			timersub(&tv_finish, &tv_start, &elapsed);
-
-			estimate_hashes = ((double)(elapsed.tv_sec) +
-					   ((double)(elapsed.tv_usec)) /
-					   ((double)1000000)) / info->Hs;
-
-			/* If Serial-USB delay allowed the full nonce range to
-			 * complete it can't have done more than a full nonce
-			 */
-			if (unlikely(estimate_hashes > 0xffffffff))
-				estimate_hashes = 0xffffffff;
-
-			applog(LOG_DEBUG,
-			       "Avalon: no nonce = 0x%08llx hashes "
-			       "(%ld.%06lds)",
-			       estimate_hashes, elapsed.tv_sec,
-			       elapsed.tv_usec);
-
+			applog(LOG_DEBUG, "Avalon: no nonce in (%ld.%06lds)",
+			       elapsed.tv_sec, elapsed.tv_usec);
 			continue;
 			continue;
 		}
 		}
 		if (ret == AVA_GETS_RESTART) {
 		if (ret == AVA_GETS_RESTART) {
@@ -747,37 +741,44 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **bulk_work,
 		work_i0 = avalon_decode_nonce(thr, bulk0, &ar, &nonce);
 		work_i0 = avalon_decode_nonce(thr, bulk0, &ar, &nonce);
 		work_i1 = avalon_decode_nonce(thr, bulk1, &ar, &nonce);
 		work_i1 = avalon_decode_nonce(thr, bulk1, &ar, &nonce);
 		work_i2 = avalon_decode_nonce(thr, bulk2, &ar, &nonce);
 		work_i2 = avalon_decode_nonce(thr, bulk2, &ar, &nonce);
+		if ((work_i0 < 0) && (work_i1 < 0) && (work_i2 < 0)) {
+			if (opt_debug) {
+				timersub(&tv_finish, &tv_start, &elapsed);
+				applog(LOG_DEBUG,"Avalon: no matching work: %d"
+				       " (%ld.%06lds)", ++no_matching_work,
+				       elapsed.tv_sec, elapsed.tv_usec);
+			}
+			continue;
+		}
 
 
-		curr_hw_errors = avalon->hw_errors;
 		if (work_i0 >= 0)
 		if (work_i0 >= 0)
 			submit_nonce(thr, bulk0[work_i0], nonce);
 			submit_nonce(thr, bulk0[work_i0], nonce);
 		if (work_i1 >= 0)
 		if (work_i1 >= 0)
 			submit_nonce(thr, bulk1[work_i1], nonce);
 			submit_nonce(thr, bulk1[work_i1], nonce);
 		if (work_i2 >= 0)
 		if (work_i2 >= 0)
 			submit_nonce(thr, bulk2[work_i2], nonce);
 			submit_nonce(thr, bulk2[work_i2], nonce);
-		was_hw_error = (curr_hw_errors > avalon->hw_errors);
-
-		/* Force a USB close/reopen on any hw error */
-		if (was_hw_error)
-			do_avalon_close(thr);
+		/* TODO: should I take care about HW, no_matching_work? */
 
 
 		hash_count += nonce;
 		hash_count += nonce;
-	}
-	avalon_free_work(thr, bulk0);
 
 
-	if (opt_debug) {
-		timersub(&tv_finish, &tv_start, &elapsed);
-		applog(LOG_DEBUG,
-		       "Avalon: nonce = 0x%08x = 0x%08llx hashes "
-		       "(%ld.%06lds)",
-		       nonce, hash_count, elapsed.tv_sec, elapsed.tv_usec);
+		if (opt_debug) {
+			timersub(&tv_finish, &tv_start, &elapsed);
+			applog(LOG_DEBUG,
+			       "Avalon: nonce = 0x%08x = 0x%08llx hashes "
+			       "(%ld.%06lds)", nonce, hash_count,
+			       elapsed.tv_sec, elapsed.tv_usec);
+		}
 	}
 	}
+	avalon_free_work(thr, bulk0);
 
 
 	applog(LOG_ERR,
 	applog(LOG_ERR,
-	       "Avalon: Fan1: %d, Fan2: %d, Fan3: %d. Temp1: %d, Temp2: %d, Temp3: %d, TempMAX: %d",
-	       info->fan0, info->fan1, info->fan2, info->temp0, info->temp1, info->temp2, info->temp_max);
+	       "Avalon: Fan1: %d, Fan2: %d, Fan3: %d\t"
+	       "Temp1: %d, Temp2: %d, Temp3: %d, TempMAX: %d",
+	       info->fan0, info->fan1, info->fan2,
+	       info->temp0, info->temp1, info->temp2, info->temp_max);
 
 
-	return (hash_count ? hash_count : ((int64_t)4*1024*1024*1024)*info->miner_count*info->asic_count);
+	return (hash_count ? hash_count :
+		((int64_t)256*1024*1024)*info->miner_count*info->asic_count);
 }
 }
 
 
 static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)
 static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)

+ 1 - 2
driver-avalon.h

@@ -50,7 +50,6 @@ struct avalon_result {
 } __attribute__((packed, aligned(4)));
 } __attribute__((packed, aligned(4)));
 
 
 struct avalon_info {
 struct avalon_info {
-	double Hs;
 	int read_count;
 	int read_count;
 
 
 	int baud;
 	int baud;
@@ -74,7 +73,7 @@ struct avalon_info {
 #define AVALON_MINER_THREADS 1
 #define AVALON_MINER_THREADS 1
 
 
 #define AVALON_IO_SPEED		115200
 #define AVALON_IO_SPEED		115200
-#define AVALON_HASH_TIME_FACTOR	(1.67/0x32)
+#define AVALON_HASH_TIME_FACTOR	((float)1.67/0x32)
 #define AVALON_RESET_PITCH	(80*1000*1000)
 #define AVALON_RESET_PITCH	(80*1000*1000)
 
 
 #define AVALON_DEFAULT_FAN_PWM 0x98
 #define AVALON_DEFAULT_FAN_PWM 0x98