Browse Source

avalon: more work on get results

Xiangfu 13 years ago
parent
commit
2f313da8e9
1 changed files with 87 additions and 83 deletions
  1. 87 83
      driver-avalon.c

+ 87 - 83
driver-avalon.c

@@ -117,12 +117,19 @@ static int avalon_gets(uint8_t *buf, int fd, struct timeval *tv_finish,
 	/* FIXME: we should set RTS to 0 and CTS to be 1, before read? */
 	int done = avalon_task_done(fd);
 	if (opt_debug)
-		applog(LOG_DEBUG, "Avalon bulk task statue: %d", done);
+		applog(LOG_DEBUG, "Avalon: finished all task?: %d", done);
 	if (done) {
-		/* TODO: return here. and tell avalon all task are done */
+		;/* TODO: return here. and tell avalon all task are done */
 	}
 	// Read reply 1 byte at a time to get earliest tv_finish
 	while (true) {
+		/* FIXME: should be remove!!! */
+		if (opt_debug) {
+			applog(LOG_DEBUG,
+			       "Avalon Read: times: %d, %.2f", rc,
+			       (float)rc/(float)TIME_FACTOR);
+		}
+
 		ret = read(fd, buf, 1);
 		if (ret < 0)
 			return AVA_GETS_ERROR;
@@ -153,31 +160,39 @@ static int avalon_gets(uint8_t *buf, int fd, struct timeval *tv_finish,
 		if (thr && thr->work_restart) {
 			if (opt_debug) {
 				applog(LOG_DEBUG,
-				   "Avalon Read: Work restart at %.2f seconds",
-				   (float)(rc)/(float)TIME_FACTOR);
+				       "Avalon Read: Work restart at %.2f seconds",
+				       (float)(rc)/(float)TIME_FACTOR);
 			}
 			return AVA_GETS_RESTART;
 		}
 	}
 }
 
-static int avalon_read_work(uint8_t *nonce_bin, int fd,
+static int avalon_get_result(uint8_t *nonce_bin, int fd,
 			    struct timeval *tv_finish, struct thr_info *thr)
 {
-	/* TODO: create a globle buffer match that buffer retrun the work*/
 	struct cgpu_info *avalon = thr->cgpu;
 	struct AVALON_INFO *info = avalon_info[avalon->device_id];
 	int ret;
 
-	memset(nonce_bin, 0, AVALON_READ_SIZE);
+	memset(nonce_bin, 0, sizeof(nonce_bin));
 	ret = avalon_gets(nonce_bin, fd, tv_finish, thr, info->read_count);
 
 	return ret;
 }
 
-static int avalon_submit_nonce(uint8_t *ob_bin)
+static int avalon_decode_nonce(struct work **work, uint32_t *nonce,
+			       uint8_t *nonce_bin)
 {
+	/* FIXME: Avalon return: reserved_nonce_midstate_data, */
+
+	/* FIXME: should be modify to avalon data format */
+	memcpy((uint8_t *)nonce, nonce_bin, sizeof(nonce_bin));
+#if !defined (__BIG_ENDIAN__) && !defined(MIPSEB)
+	*nonce = swab32(*nonce);
+#endif
 
+	/* TODO: find the nonce work, return index */
 	return 0;
 }
 
@@ -187,16 +202,16 @@ static int avalon_send_task(int fd, const void *buf, size_t bufLen)
 
 	/* FIXME: we should set RTS to 1 and wait CTS became 1, before write? */
 	int empty = avalon_buffer_empty(fd);
-	if (empty < 0) {
-		/* FIXME: ERROR */
-	}
+	if (empty < 0)
+		return AVA_SEND_ERROR;
+
 	if (!empty) {
-		/* FIXME: the buffer was full */
+		/* FIXME: the buffer was full; return AVA_SEND_FULL; */
 	}
 
 	ret = write(fd, buf, bufLen);
 	if (unlikely(ret != bufLen))
-		return 1;
+		return AVA_SEND_ERROR;
 
 	/* From the document. avalon needs some time space between two write */
 	struct timespec p;
@@ -204,7 +219,7 @@ static int avalon_send_task(int fd, const void *buf, size_t bufLen)
 	p.tv_nsec = 5 * 1000;
 	nanosleep(&p, NULL);
 
-	return 0;
+	return AVA_SEND_OK;
 }
 
 #define avalon_close(fd) close(fd)
@@ -297,7 +312,6 @@ static void set_timing_mode(int this_option_offset, struct cgpu_info *avalon)
 		info->do_avalon_timing = false;
 	} else {
 		// Anything else in buf just uses DEFAULT mode
-
 		info->Hs = AVALON_REV3_HASH_TIME;
 		info->fullnonce = info->Hs * (((double)0xffffffff) + 1);
 
@@ -447,12 +461,6 @@ static void get_options(int this_option_offset, int *baud, int *work_division,
 
 static bool avalon_detect_one(const char *devpath)
 {
-	int this_option_offset = ++option_offset;
-
-	struct AVALON_INFO *info;
-	struct timeval tv_start, tv_finish;
-	int fd;
-
 	// Block 171874 nonce = (0xa2870100) = 0x000187a2
 	// N.B. golden_ob MUST take less time to calculate
 	//	than the timeout set in avalon_open()
@@ -469,12 +477,15 @@ static bool avalon_detect_one(const char *devpath)
 	uint8_t ob_bin[64], nonce_bin[AVALON_READ_SIZE];
 	char *nonce_hex;
 
-	int baud, work_division, asic_count;
+	struct AVALON_INFO *info;
+	struct timeval tv_start, tv_finish;
+	int fd;
 
+	int baud, work_division, asic_count;
+	int this_option_offset = ++option_offset;
 	get_options(this_option_offset, &baud, &work_division, &asic_count);
 
 	applog(LOG_DEBUG, "Avalon Detect: Attempting to open %s", devpath);
-
 	fd = avalon_open2(devpath, baud, true);
 	if (unlikely(fd == -1)) {
 		applog(LOG_ERR, "Avalon Detect: Failed to open %s", devpath);
@@ -486,7 +497,8 @@ static bool avalon_detect_one(const char *devpath)
 	gettimeofday(&tv_start, NULL);
 
 	memset(nonce_bin, 0, sizeof(nonce_bin));
-	avalon_gets(nonce_bin, fd, &tv_finish, NULL, 1);
+	/* FIXME: how much time on avalon finish reset */ 
+	avalon_gets(nonce_bin, fd, &tv_finish, NULL, 10/* set to 1s now */);
 
 	avalon_close(fd);
 
@@ -500,9 +512,8 @@ static bool avalon_detect_one(const char *devpath)
 		return false;
 	}
 	applog(LOG_DEBUG,
-		"Avalon Detect: "
-		"Test succeeded at %s: got %s",
-			devpath, nonce_hex);
+	       "Avalon Detect: Test succeeded at %s: got %s",
+	       devpath, nonce_hex);
 	free(nonce_hex);
 
 	/* We have a real Avalon! */
@@ -540,9 +551,8 @@ static bool avalon_detect_one(const char *devpath)
 	info->work_division = work_division;
 	info->asic_count = asic_count;
 	info->nonce_mask = mask(work_division);
-
-	info->golden_hashes = (golden_nonce_val & info->nonce_mask) *
-		asic_count;
+	info->golden_hashes =
+		(golden_nonce_val & info->nonce_mask) * asic_count;
 	timersub(&tv_finish, &tv_start, &(info->golden_tv));
 
 	set_timing_mode(this_option_offset, avalon);
@@ -550,7 +560,7 @@ static bool avalon_detect_one(const char *devpath)
 	return true;
 }
 
-static void avalon_detect()
+static inline void avalon_detect()
 {
 	serial_detect(&avalon_api, avalon_detect_one);
 }
@@ -558,19 +568,17 @@ static void avalon_detect()
 static bool avalon_prepare(struct thr_info *thr)
 {
 	struct cgpu_info *avalon = thr->cgpu;
-
 	struct timeval now;
+	int fd;
 
 	avalon->device_fd = -1;
-
-	int fd = avalon_open(avalon->device_path,
+	fd = avalon_open(avalon->device_path,
 			     avalon_info[avalon->device_id]->baud);
-	if (unlikely(-1 == fd)) {
+	if (unlikely(fd == -1)) {
 		applog(LOG_ERR, "Failed to open Avalon on %s",
 		       avalon->device_path);
 		return false;
 	}
-
 	avalon->device_fd = fd;
 
 	applog(LOG_INFO, "Opened Avalon on %s", avalon->device_path);
@@ -593,16 +601,19 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **work,
 	char *ob_hex;
 	uint32_t nonce;
 	int64_t hash_count;
+	int i, work_i;
+	int read_count;
+	int count;
+
 	struct timeval tv_start, tv_finish, elapsed;
 	struct timeval tv_history_start, tv_history_finish;
 	double Ti, Xi;
-	int curr_hw_errors, i;
+
+	int curr_hw_errors;
 	bool was_hw_error;
 
 	struct AVALON_HISTORY *history0, *history;
-	int count;
 	double Hs, W, fullnonce;
-	int read_count;
 	int64_t estimate_hashes;
 	uint32_t values;
 	int64_t hash_count_range;
@@ -622,7 +633,7 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **work,
 #ifndef WIN32
 	tcflush(fd, TCOFLUSH);
 #endif
-
+	/* Write task to device one by one */
 	for (i = 0; i < AVALON_GET_WORK_COUNT; i++) {
 		avalon_create_task(ob_bin, work[i]);
 		ret = avalon_send_task(fd, ob_bin, sizeof(ob_bin));
@@ -632,7 +643,7 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **work,
 			       avalon->device_id, ob_hex);
 			free(ob_hex);
 		}
-		if (ret) {
+		if (ret == AVA_SEND_ERROR) {
 			do_avalon_close(thr);
 			applog(LOG_ERR, "AVA%i: Comms error",
 			       avalon->device_id);
@@ -644,64 +655,57 @@ static int64_t avalon_scanhash(struct thr_info *thr, struct work **work,
 	elapsed.tv_sec = elapsed.tv_usec = 0;
 	gettimeofday(&tv_start, NULL);
 
-	/* FIXME: all read should be in another function
-	   Avalon return: reserved_nonce_midstate_data,
-	   count != AVALON_GET_WORK_COUNT */
+	/* count may != AVALON_GET_WORK_COUNT */
 	for (i = 0; i < AVALON_GET_WORK_COUNT; i++) {
-		ret = avalon_read_work(nonce_bin, fd, &tv_finish, thr);
+		ret = avalon_get_result(nonce_bin, fd, &tv_finish, thr);
 		if (ret == AVA_GETS_ERROR ) {
 			do_avalon_close(thr);
 			applog(LOG_ERR, "AVA%i: Comms error", avalon->device_id);
 			dev_error(avalon, REASON_DEV_COMMS_ERROR);
 			return 0;
 		}
-		work[0]->blk.nonce = 0xffffffff;
-	}
 
+		// aborted before becoming idle, get new work
+		if (ret == AVA_GETS_TIMEOUT || ret == AVA_GETS_RESTART) {
+			timersub(&tv_finish, &tv_start, &elapsed);
 
-	// aborted before becoming idle, get new work
-	if (ret == AVA_GETS_TIMEOUT || ret == AVA_GETS_RESTART) {
-		timersub(&tv_finish, &tv_start, &elapsed);
+			// ONLY up to just when it aborted
+			// We didn't read a reply so we don't subtract AVALON_READ_TIME
+			estimate_hashes = ((double)(elapsed.tv_sec) +
+					   ((double)(elapsed.tv_usec)) /
+					   ((double)1000000)) / info->Hs;
 
-		// ONLY up to just when it aborted
-		// We didn't read a reply so we don't subtract AVALON_READ_TIME
-		estimate_hashes = ((double)(elapsed.tv_sec) +
-				   ((double)(elapsed.tv_usec)) /
-				   ((double)1000000)) / info->Hs;
+			// If some 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;
 
-		// If some 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;
+			if (opt_debug) {
+				applog(LOG_DEBUG,
+				       "Avalon %d no nonce = 0x%08llx hashes "
+				       "(%ld.%06lds)",
+				       avalon->device_id, estimate_hashes,
+				       elapsed.tv_sec, elapsed.tv_usec);
+			}
 
-		if (opt_debug) {
-			applog(LOG_DEBUG,
-			       "Avalon %d no nonce = 0x%08llx hashes "
-			       "(%ld.%06lds)",
-			       avalon->device_id, estimate_hashes,
-			       elapsed.tv_sec, elapsed.tv_usec);
+			return estimate_hashes;
 		}
 
-		return estimate_hashes;
-	}
-
-	memcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin));
+		work_i = avalon_decode_nonce(work, &nonce, nonce_bin);
+		/* FIXME: Should be a check on return, no work_i maybe hardware error */
+		work[work_i]->blk.nonce = 0xffffffff;
+		curr_hw_errors = avalon->hw_errors;
+		submit_nonce(thr, work[work_i], nonce);
+		was_hw_error = (curr_hw_errors > avalon->hw_errors);
 
-#if !defined (__BIG_ENDIAN__) && !defined(MIPSEB)
-	nonce = swab32(nonce);
-#endif
-
-	curr_hw_errors = avalon->hw_errors;
-	submit_nonce(thr, work[0], 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);
+		// Force a USB close/reopen on any hw error
+		if (was_hw_error)
+			do_avalon_close(thr);
 
-	hash_count = (nonce & info->nonce_mask);
-	hash_count++;
-	hash_count *= info->asic_count;
+		hash_count = (nonce & info->nonce_mask);
+		hash_count++;
+		hash_count *= info->asic_count;
+	}
 
 	if (opt_debug || info->do_avalon_timing)
 		timersub(&tv_finish, &tv_start, &elapsed);