Commit 57a72d51fb60625ba2432637f82a79f34ca30d07

nelisky 2012-05-02T07:26:52

Blind implementation of multi-fpga board 1.15y.

diff --git a/driver-ztex.c b/driver-ztex.c
index a938cae..fc4b243 100644
--- a/driver-ztex.c
+++ b/driver-ztex.c
@@ -30,17 +30,37 @@
 
 #define GOLDEN_BACKLOG 5
 
-struct device_api ztex_api, ztex_hotplug_api;
+struct device_api ztex_api;
 
 // Forward declarations
 static void ztex_disable(struct thr_info* thr);
 static bool ztex_prepare(struct thr_info *thr);
 
+static void ztex_selectFpga(struct libztex_device* ztex)
+{
+	if (ztex->root->numberOfFpgas > 1) {
+		if (ztex->root->selectedFpga != ztex->fpgaNum)
+			mutex_lock(&ztex->root->mutex);
+		libztex_selectFpga(ztex);
+	}
+}
+
+static void ztex_releaseFpga(struct libztex_device* ztex)
+{
+	if (ztex->root->numberOfFpgas > 1) {
+		ztex->root->selectedFpga = -1;
+		mutex_unlock(&ztex->root->mutex);
+	}
+}
+
 static void ztex_detect(void)
 {
 	int cnt;
-	int i;
+	int i,j;
+	int fpgacount;
 	struct libztex_dev_list **ztex_devices;
+	struct libztex_device *ztex_slave;
+	struct cgpu_info *ztex;
 
 	cnt = libztex_scanDevices(&ztex_devices);
 	applog(LOG_WARNING, "Found %d ztex board(s)", cnt);
@@ -48,14 +68,30 @@ static void ztex_detect(void)
 	for (i = 0; i < cnt; i++) {
 		if (total_devices == MAX_DEVICES)
 			break;
-		struct cgpu_info *ztex;
 		ztex = calloc(1, sizeof(struct cgpu_info));
 		ztex->api = &ztex_api;
 		ztex->device_ztex = ztex_devices[i]->dev;
 		ztex->threads = 1;
+		ztex->device_ztex->fpgaNum = 0;
+		ztex->device_ztex->root = ztex->device_ztex;
 		add_cgpu(ztex);
 
-		applog(LOG_WARNING,"%s: Found Ztex, mark as %d", ztex->device_ztex->repr, ztex->device_id);
+		fpgacount = libztex_numberOfFpgas(ztex->device_ztex);
+
+		if (fpgacount > 1)
+			pthread_mutex_init(&ztex->device_ztex->mutex, NULL);
+
+		for (j = 1; j < fpgacount; j++) {
+			ztex = calloc(1, sizeof(struct cgpu_info));
+			ztex->api = &ztex_api;
+			ztex_slave = calloc(1, sizeof(struct libztex_device));
+			memcpy(ztex_slave, ztex_devices[i]->dev, sizeof(struct libztex_device));
+			ztex->device_ztex = ztex_slave;
+			ztex_slave->root = ztex_devices[i]->dev;
+			ztex_slave->fpgaNum = j;
+		}
+
+		applog(LOG_WARNING,"%s: Found Ztex (fpga count = %d) , mark as %d", ztex->device_ztex->repr, fpgacount, ztex->device_id);
 	}
 
 	if (cnt > 0)
@@ -88,16 +124,18 @@ static bool ztex_updateFreq(struct libztex_device* ztex)
 	}
 
 	if (bestM != ztex->freqM) {
-		libztex_selectFpga(ztex, 0);
+		ztex_selectFpga(ztex);
 		libztex_setFreq(ztex, bestM);
+		ztex_releaseFpga(ztex);
 	}
 
 	maxM = ztex->freqMDefault;
 	while (maxM < ztex->freqMaxM && ztex->errorWeight[maxM + 1] > 100)
 		maxM++;
 	if ((bestM < (1.0 - LIBZTEX_OVERHEATTHRESHOLD) * maxM) && bestM < maxM - 1) {
-		libztex_selectFpga(ztex, 0);
+		ztex_selectFpga(ztex);
 		libztex_resetFpga(ztex);
+		ztex_releaseFpga(ztex);
 		applog(LOG_ERR, "%s: frequency drop of %.1f%% detect. This may be caused by overheating. FPGA is shut down to prevent damage.",
 		       ztex->repr, (1.0 - 1.0 * bestM / maxM) * 100);
 		return false;
@@ -163,7 +201,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 	memcpy(sendbuf, work->data + 64, 12);
 	memcpy(sendbuf + 12, work->midstate, 32);
 	
-	libztex_selectFpga(ztex, 0);
+	ztex_selectFpga(ztex);
 	i = libztex_sendHashData(ztex, sendbuf);
 	if (i < 0) {
 		// Something wrong happened in send
@@ -174,9 +212,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 			// And there's nothing we can do about it
 			ztex_disable(thr);
 			applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i);
+			ztex_releaseFpga(ztex);
 			return 0;
 		}
 	}
+	ztex_releaseFpga(ztex);
 	
 	applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr);
 
@@ -204,7 +244,7 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
 			break;
 		}
-		libztex_selectFpga(ztex, 0);
+		ztex_selectFpga(ztex);
 		i = libztex_readHashData(ztex, &hdata[0]);
 		if (i < 0) {
 			// Something wrong happened in read
@@ -217,9 +257,11 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 				applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
 				free(lastnonce);
 				free(backlog);
+				ztex_releaseFpga(ztex);
 				return 0;
 			}
 		}
+		ztex_releaseFpga(ztex);
 
 		if (work_restart[thr->id].restart) {
 			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
@@ -310,24 +352,27 @@ static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
 static bool ztex_prepare(struct thr_info *thr)
 {
 	struct timeval now;
-	struct cgpu_info *ztex = thr->cgpu;
+	struct cgpu_info *cgpu = thr->cgpu;
+	struct libztex_device *ztex = cgpu->device_ztex;
 
 	gettimeofday(&now, NULL);
-	get_datestamp(ztex->init, &now);
-
-	if (libztex_configureFpga(ztex->device_ztex) != 0)
+	get_datestamp(cgpu->init, &now);
+	
+	libztex_selectFpga(ztex);
+	if (libztex_configureFpga(ztex) != 0)
 		return false;
-
-	ztex->device_ztex->freqM = -1;
-	ztex_updateFreq(ztex->device_ztex);
-
-	applog(LOG_DEBUG, "%s: prepare", ztex->device_ztex->repr);
+	ztex_releaseFpga(ztex);
+	ztex->freqM = -1;
+	ztex_updateFreq(ztex);
+	applog(LOG_DEBUG, "%s: prepare", ztex->repr);
 	return true;
 }
 
 static void ztex_shutdown(struct thr_info *thr)
 {
 	if (thr->cgpu->device_ztex != NULL) {
+		if (thr->cgpu->device_ztex->fpgaNum == 0)
+			pthread_mutex_destroy(&thr->cgpu->device_ztex->mutex);  
 		applog(LOG_DEBUG, "%s: shutdown", thr->cgpu->device_ztex->repr);
 		libztex_destroy_device(thr->cgpu->device_ztex);
 		thr->cgpu->device_ztex = NULL;
@@ -350,3 +395,4 @@ struct device_api ztex_api = {
 	.scanhash = ztex_scanhash,
 	.thread_shutdown = ztex_shutdown,
 };
+
diff --git a/libztex.c b/libztex.c
index a73130f..29a226a 100644
--- a/libztex.c
+++ b/libztex.c
@@ -339,19 +339,20 @@ int libztex_numberOfFpgas(struct libztex_device *ztex) {
 				return cnt;
 			}
 			ztex->numberOfFpgas = buf[0] + 1;
-			ztex->selectedFpga = buf[1];
+			ztex->selectedFpga = -1;//buf[1];
 			ztex->parallelConfigSupport = (buf[2] == 1);
 		} else {
 			ztex->numberOfFpgas = 1;
-			ztex->selectedFpga = 0;
+			ztex->selectedFpga = -1;//0;
 			ztex->parallelConfigSupport = false;
 		}
 	}
 	return ztex->numberOfFpgas;
 }
 
-int libztex_selectFpga(struct libztex_device *ztex, int number) {
+int libztex_selectFpga(struct libztex_device *ztex) {
 	int cnt, fpgacnt = libztex_numberOfFpgas(ztex);
+	int number = ztex->fpgaNum;
 	if (number < 0 || number >= fpgacnt) {
 		applog(LOG_WARNING, "%s: Trying to select wrong fpga (%d in %d)", ztex->repr, number, fpgacnt);
 		return 1;
@@ -380,8 +381,12 @@ int libztex_setFreq(struct libztex_device *ztex, uint16_t freq) {
 		return cnt;
 	}
 	ztex->freqM = freq;
-	applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz",
-	       ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1));
+	if (oldfreq == -1) 
+		applog(LOG_WARNING, "%s: Frequency set to %0.2f Mhz",
+		       ztex->repr, ztex->freqM1 * (ztex->freqM + 1));
+	else
+		applog(LOG_WARNING, "%s: Frequency change from %0.2f to %0.2f Mhz",
+		       ztex->repr, ztex->freqM1 * (oldfreq + 1), ztex->freqM1 * (ztex->freqM + 1));
 
 	return 0;
 }
diff --git a/libztex.h b/libztex.h
index f95fc99..287b618 100644
--- a/libztex.h
+++ b/libztex.h
@@ -44,6 +44,9 @@ struct libztex_fpgastate {
 };
 
 struct libztex_device {
+	pthread_mutex_t	mutex;
+	struct libztex_device *root;
+	int fpgaNum;
 	bool valid;
 	struct libusb_device_descriptor descriptor;
 	libusb_device_handle *hndl; 
@@ -98,6 +101,7 @@ extern int libztex_setFreq (struct libztex_device *ztex, uint16_t freq);
 extern int libztex_sendHashData (struct libztex_device *ztex, unsigned char *sendbuf);
 extern int libztex_readHashData (struct libztex_device *ztex, struct libztex_hash_data nonces[]);
 extern int libztex_resetFpga (struct libztex_device *ztex);
-extern int libztex_selectFpga(struct libztex_device *ztex, int number);
+extern int libztex_selectFpga(struct libztex_device *ztex);
+extern int libztex_numberOfFpgas(struct libztex_device *ztex);
 
 #endif /* __LIBZTEX_H__ */