Browse Source

avalon: Go back to good old serial timeouts for gets, since select() is for sockets (only, on Windows)

This reverts commits af65870244aa80230cdd8c014b39e0304d20b479, af6111fb555f195574120ec19439662d1eb3d740, 5e3474b0c8ef95c3b08ae587c138ea136fcc8362, 3671b2c310d875ad160dd9918fcc8d48c0ab7be6, d013551862928bdfaf5cc31a1750e69917e8bb4b.
Luke Dashjr 12 years ago
parent
commit
eba5e7cf77
2 changed files with 46 additions and 35 deletions
  1. 43 35
      driver-avalon.c
  2. 3 0
      driver-avalon.h

+ 43 - 35
driver-avalon.c

@@ -202,66 +202,71 @@ static int avalon_send_task(int fd, const struct avalon_task *at,
 	return AVA_SEND_BUFFER_EMPTY;
 	return AVA_SEND_BUFFER_EMPTY;
 }
 }
 
 
-static inline int avalon_gets(int fd, uint8_t *buf, struct thr_info *thr,
-		       struct timeval *tv_finish)
+static inline int avalon_gets(int fd, uint8_t *buf, int read_count,
+		       struct thr_info *thr, struct timeval *tv_finish)
 {
 {
+	ssize_t ret = 0;
+	int rc = 0;
 	int read_amount = AVALON_READ_SIZE;
 	int read_amount = AVALON_READ_SIZE;
 	bool first = true;
 	bool first = true;
-	ssize_t ret = 0;
 
 
+	/* Read reply 1 byte at a time to get earliest tv_finish */
 	while (true) {
 	while (true) {
-		struct timeval timeout;
-		fd_set rd;
-
-		if (unlikely(thr->work_restart)) {
-			applog(LOG_DEBUG, "Avalon: Work restart");
-			return AVA_GETS_RESTART;
+		ret = read(fd, buf, 1);
+		if (ret < 0)
+		{
+			applog(LOG_ERR, "Avalon: Error %d on read in avalon_gets", errno);
+			return AVA_GETS_ERROR;
 		}
 		}
 
 
-		timeout.tv_sec = 0;
-		timeout.tv_usec = 100000;
+		if (first && likely(tv_finish))
+			cgtime(tv_finish);
 
 
-		FD_ZERO(&rd);
-		FD_SET(fd, &rd);
-		ret = select(fd + 1, &rd, NULL, NULL, &timeout);
-		if (unlikely(ret < 0)) {
-			applog(LOG_ERR, "Avalon: Error %d on select in avalon_gets", errno);
-			return AVA_GETS_ERROR;
-		}
-		if (ret) {
-			ret = read(fd, buf, read_amount);
-			if (unlikely(ret < 0)) {
-				applog(LOG_ERR, "Avalon: Error %d on read in avalon_gets", errno);
-				return AVA_GETS_ERROR;
-			}
-			if (likely(first)) {
-				cgtime(tv_finish);
-				first = false;
-			}
-			if (likely(ret >= read_amount))
-				return AVA_GETS_OK;
+		if (ret >= read_amount)
+			return AVA_GETS_OK;
+
+		if (ret > 0) {
 			buf += ret;
 			buf += ret;
 			read_amount -= ret;
 			read_amount -= ret;
+			first = false;
 			continue;
 			continue;
 		}
 		}
 
 
-		if (unlikely(thr->work_restart)) {
-			applog(LOG_DEBUG, "Avalon: Work restart");
+		if (thr && thr->work_restart) {
+			if (opt_debug) {
+				applog(LOG_WARNING,
+				       "Avalon: Work restart at %.2f seconds",
+				       (float)(rc)/(float)AVALON_TIME_FACTOR);
+			}
 			return AVA_GETS_RESTART;
 			return AVA_GETS_RESTART;
 		}
 		}
 
 
-		return AVA_GETS_TIMEOUT;
+		rc++;
+		if (rc >= read_count) {
+			if (opt_debug) {
+				applog(LOG_WARNING,
+				       "Avalon: No data in %.2f seconds",
+				       (float)rc/(float)AVALON_TIME_FACTOR);
+			}
+			return AVA_GETS_TIMEOUT;
+		}
 	}
 	}
 }
 }
 
 
 static int avalon_get_result(int fd, struct avalon_result *ar,
 static int avalon_get_result(int fd, struct avalon_result *ar,
 			     struct thr_info *thr, struct timeval *tv_finish)
 			     struct thr_info *thr, struct timeval *tv_finish)
 {
 {
+	struct cgpu_info *avalon;
+	struct avalon_info *info;
 	uint8_t result[AVALON_READ_SIZE];
 	uint8_t result[AVALON_READ_SIZE];
-	int ret;
+	int ret, read_count;
+
+	avalon = thr->cgpu;
+	info = avalon->device_data;
+	read_count = info->read_count;
 
 
 	memset(result, 0, AVALON_READ_SIZE);
 	memset(result, 0, AVALON_READ_SIZE);
-	ret = avalon_gets(fd, result, thr, tv_finish);
+	ret = avalon_gets(fd, result, read_count, thr, tv_finish);
 
 
 	if (ret == AVA_GETS_OK) {
 	if (ret == AVA_GETS_OK) {
 		if (opt_debug) {
 		if (opt_debug) {
@@ -612,6 +617,8 @@ static bool avalon_detect_one(const char *devpath)
 	info->miner_count = miner_count;
 	info->miner_count = miner_count;
 	info->asic_count = asic_count;
 	info->asic_count = asic_count;
 	info->timeout = timeout;
 	info->timeout = timeout;
+	info->read_count = ((float)info->timeout * AVALON_HASH_TIME_FACTOR *
+			    AVALON_TIME_FACTOR) / (float)info->miner_count;
 
 
 	info->fan_pwm = AVALON_DEFAULT_FAN_MIN_PWM;
 	info->fan_pwm = AVALON_DEFAULT_FAN_MIN_PWM;
 	info->temp_max = 0;
 	info->temp_max = 0;
@@ -1002,6 +1009,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)
 	root = api_add_int(root, "baud", &(info->baud), false);
 	root = api_add_int(root, "baud", &(info->baud), false);
 	root = api_add_int(root, "miner_count", &(info->miner_count),false);
 	root = api_add_int(root, "miner_count", &(info->miner_count),false);
 	root = api_add_int(root, "asic_count", &(info->asic_count), false);
 	root = api_add_int(root, "asic_count", &(info->asic_count), false);
+	root = api_add_int(root, "read_count", &(info->read_count), false);
 	root = api_add_int(root, "timeout", &(info->timeout), false);
 	root = api_add_int(root, "timeout", &(info->timeout), false);
 	root = api_add_int(root, "frequency", &(info->frequency), false);
 	root = api_add_int(root, "frequency", &(info->frequency), false);
 
 

+ 3 - 0
driver-avalon.h

@@ -13,6 +13,7 @@
 
 
 #ifdef USE_AVALON
 #ifdef USE_AVALON
 
 
+#define AVALON_TIME_FACTOR 10
 #define AVALON_RESET_FAULT_DECISECONDS 1
 #define AVALON_RESET_FAULT_DECISECONDS 1
 #define AVALON_MINER_THREADS 1
 #define AVALON_MINER_THREADS 1
 
 
@@ -75,6 +76,8 @@ struct avalon_result {
 } __attribute__((packed, aligned(4)));
 } __attribute__((packed, aligned(4)));
 
 
 struct avalon_info {
 struct avalon_info {
+	int read_count;
+
 	int baud;
 	int baud;
 	int miner_count;
 	int miner_count;
 	int asic_count;
 	int asic_count;