Commit 636c7fd495d3bb197d2d44ed6f7c776f0f102a07

Con Kolivas 2013-12-29T14:53:17

55nm avalon requires the delays between writes reinstated for stability.

diff --git a/driver-avalon.c b/driver-avalon.c
index 3e3a6d7..96eaeea 100644
--- a/driver-avalon.c
+++ b/driver-avalon.c
@@ -147,10 +147,12 @@ static int avalon_write(struct cgpu_info *avalon, char *buf, ssize_t len, int ep
 	return AVA_SEND_OK;
 }
 
-static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *avalon)
+static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *avalon,
+			    struct avalon_info *info)
+
 {
 	uint8_t buf[AVALON_WRITE_SIZE + 4 * AVALON_DEFAULT_ASIC_NUM];
-	int ret, i, ep = C_AVALON_TASK;
+	int delay, ret, i, ep = C_AVALON_TASK;
 	uint32_t nonce_range;
 	size_t nr_len;
 
@@ -191,6 +193,10 @@ static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *aval
 	tt |= ((buf[4] & 0x80) ? (1 << 0) : 0);
 	buf[4] = tt;
 #endif
+	delay = nr_len * 10 * 1000000;
+	delay = delay / info->baud;
+	delay += 4000;
+
 	if (at->reset) {
 		ep = C_AVALON_RESET;
 		nr_len = 1;
@@ -199,8 +205,15 @@ static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *aval
 		applog(LOG_DEBUG, "Avalon: Sent(%u):", (unsigned int)nr_len);
 		hexdump(buf, nr_len);
 	}
+	/* Sleep from the last time we sent data */
+	cgsleep_us_r(&info->cgsent, info->send_delay);
+
+	cgsleep_prepare_r(&info->cgsent);
 	ret = avalon_write(avalon, (char *)buf, nr_len, ep);
 
+	applog(LOG_DEBUG, "Avalon: Sent: Buffer delay: %dus", info->send_delay);
+	info->send_delay = delay;
+
 	return ret;
 }
 
@@ -332,7 +345,7 @@ static int avalon_reset(struct cgpu_info *avalon, bool initial)
 			 AVALON_A3256);
 
 	wait_avalon_ready(avalon);
-	ret = avalon_send_task(&at, avalon);
+	ret = avalon_send_task(&at, avalon, info);
 	if (unlikely(ret == AVA_SEND_ERROR))
 		return -1;
 
@@ -584,7 +597,7 @@ static void avalon_idle(struct cgpu_info *avalon, struct avalon_info *info)
 		avalon_init_task(&at, 0, 0, info->fan_pwm, info->timeout,
 				 info->asic_count, info->miner_count, 1, 1,
 				 info->frequency, info->asic);
-		if (avalon_send_task(&at, avalon) == AVA_SEND_ERROR)
+		if (avalon_send_task(&at, avalon, info) == AVA_SEND_ERROR)
 			break;
 	}
 	applog(LOG_WARNING, "%s%i: Idling %d miners", avalon->drv->name, avalon->device_id, i);
@@ -1182,7 +1195,7 @@ static void *avalon_send_tasks(void *userdata)
 			}
 			mutex_unlock(&info->qlock);
 
-			ret = avalon_send_task(&at, avalon);
+			ret = avalon_send_task(&at, avalon, info);
 
 			if (unlikely(ret == AVA_SEND_ERROR)) {
 				/* Send errors are fatal */
diff --git a/driver-avalon.h b/driver-avalon.h
index 18870c9..07a36fd 100644
--- a/driver-avalon.h
+++ b/driver-avalon.h
@@ -150,6 +150,8 @@ struct avalon_info {
 	pthread_mutex_t lock;
 	pthread_mutex_t qlock;
 	cgsem_t qsem;
+	cgtimer_t cgsent;
+	int send_delay;
 
 	int nonces;
 	int auto_queued;