Browse Source

Merge branch 'rockminer' into bfgminer

Luke Dashjr 11 years ago
parent
commit
ae56038b02
1 changed files with 26 additions and 5 deletions
  1. 26 5
      driver-rockminer.c

+ 26 - 5
driver-rockminer.c

@@ -26,6 +26,7 @@
 #define ROCKMINER_RETRY_US  5000000
 #define ROCKMINER_MIDTASK_TIMEOUT_US  500000
 #define ROCKMINER_MIDTASK_RETRY_US   1000000
+#define ROCKMINER_TASK_TIMEOUT_US    5273438
 
 #define ROCKMINER_MAX_CHIPS  64
 #define ROCKMINER_WORK_REQ_SIZE  0x40
@@ -45,6 +46,7 @@ struct rockminer_chip_data {
 	struct work *works[2];
 	uint8_t last_taskid;
 	struct timeval tv_midtask_timeout;
+	int requested_work;
 };
 
 static
@@ -268,10 +270,11 @@ bool rockminer_queue_append(struct thr_info * const thr, struct work * const wor
 	struct rockminer_chip_data * const chip = thr->cgpu_data;
 	const int fd = dev->device_fd;
 	
-	thr->queue_full = true;
-	
-	if (fd < 0)
+	if (fd < 0 || !chip->requested_work)
+	{
+		thr->queue_full = true;
 		return false;
+	}
 	
 	memcpy(&chip->next_work_req[   0], work->midstate, 0x20);
 	memcpy(&chip->next_work_req[0x34], &work->data[0x40], 0xc);
@@ -286,8 +289,12 @@ bool rockminer_queue_append(struct thr_info * const thr, struct work * const wor
 	if (chip->works[chip->last_taskid])
 		free_work(chip->works[chip->last_taskid]);
 	chip->works[chip->last_taskid] = work;
+	timer_set_delay_from_now(&chip->tv_midtask_timeout, ROCKMINER_MIDTASK_RETRY_US);
 	applog(LOG_DEBUG, "%"PRIpreprv": Work %d queued as task %d", proc->proc_repr, work->id, chip->last_taskid);
 	
+	if (!--chip->requested_work)
+		thr->queue_full = true;
+	
 	return true;
 }
 
@@ -319,13 +326,16 @@ void rockminer_poll(struct thr_info * const master_thr)
 			applogr(, LOG_ERR, "%s: Failed to open %s", dev->dev_repr, dev->device_path);
 		}
 		dev->device_fd = fd;
+		struct timeval tv_timeout;
+		timer_set_delay_from_now(&tv_timeout, ROCKMINER_TASK_TIMEOUT_US);
 		for_each_managed_proc(proc, dev)
 		{
 			struct thr_info * const thr = proc->thr[0];
 			struct rockminer_chip_data * const chip = thr->cgpu_data;
 			
+			chip->requested_work = 1;
 			thr->queue_full = false;
-			timer_unset(&chip->tv_midtask_timeout);
+			chip->tv_midtask_timeout = tv_timeout;
 		}
 	}
 	
@@ -382,7 +392,8 @@ void rockminer_poll(struct thr_info * const master_thr)
 			case ROCKMINER_REPLY_GET_TASK:
 				applog(LOG_DEBUG, "%"PRIpreprv": Task %d requested", proc->proc_repr, taskid);
 				thr->queue_full = false;
-				timer_unset(&chip->tv_midtask_timeout);
+				++chip->requested_work;
+				timer_set_delay_from_now(&chip->tv_midtask_timeout, ROCKMINER_TASK_TIMEOUT_US);
 				break;
 		}
 	}
@@ -403,6 +414,16 @@ void rockminer_poll(struct thr_info * const master_thr)
 			applog(LOG_WARNING, "%"PRIpreprv": No task request? Probably lost, resending task %d", proc->proc_repr, chip->last_taskid);
 			inc_hw_errors_only(thr);
 			timer_set_delay(&chip->tv_midtask_timeout, &tv_now, ROCKMINER_MIDTASK_RETRY_US);
+			struct work *work;
+			if ((!(work = chip->works[chip->last_taskid])) || stale_work(work, false))
+			{
+				// Either no work was queued, or it was stale
+				// Instead of resending, just queue a new one
+				if (!chip->requested_work)
+					chip->requested_work = 1;
+				thr->queue_full = false;
+			}
+			else
 			if (!rockminer_send_work(thr))
 			{
 				rockminer_dead(dev);