Browse Source

bitforce: XLINK support for multiple processors

Luke Dashjr 13 years ago
parent
commit
ab883d97ba
1 changed files with 59 additions and 24 deletions
  1. 59 24
      driver-bitforce.c

+ 59 - 24
driver-bitforce.c

@@ -60,20 +60,46 @@ static ssize_t BFwrite(int fd, const void *buf, ssize_t bufLen)
 		return bufLen;
 }
 
+static ssize_t bitforce_send(int fd, int procid, const void *buf, ssize_t bufLen)
+{
+	if (!procid)
+		return BFwrite(fd, buf, bufLen);
+	
+	if (bufLen > 255)
+		return -1;
+	
+	size_t bufLeft = bufLen + 3;
+	char realbuf[bufLeft], *bufp;
+	ssize_t rv;
+	memcpy(&realbuf[3], buf, bufLen);
+	realbuf[0] = '@';
+	realbuf[1] = procid;
+	realbuf[2] = bufLen;
+	bufp = realbuf;
+	while (true)
+	{
+		rv = BFwrite(fd, bufp, bufLeft);
+		if (rv <= 0)
+			return rv;
+		bufLeft -= rv;
+	}
+	return bufLen;
+}
+
 static
-void bitforce_cmd1(int fd, void *buf, size_t bufsz, const char *cmd)
+void bitforce_cmd1(int fd, int procid, void *buf, size_t bufsz, const char *cmd)
 {
-	BFwrite(fd, cmd, 3);
+	bitforce_send(fd, procid, cmd, 3);
 	BFgets(buf, bufsz, fd);
 }
 
 static
-void bitforce_cmd2(int fd, void *buf, size_t bufsz, const char *cmd, void *data, size_t datasz)
+void bitforce_cmd2(int fd, int procid, void *buf, size_t bufsz, const char *cmd, void *data, size_t datasz)
 {
-	bitforce_cmd1(fd, buf, bufsz, cmd);
+	bitforce_cmd1(fd, procid, buf, bufsz, cmd);
 	if (strncasecmp(buf, "OK", 2))
 		return;
-	BFwrite(fd, data, datasz);
+	bitforce_send(fd, procid, data, datasz);
 	BFgets(buf, bufsz, fd);
 }
 
@@ -86,6 +112,7 @@ static bool bitforce_detect_one(const char *devpath)
 	char pdevbuf[0x100];
 	size_t pdevbuf_len;
 	char *s;
+	int procs = 1;
 
 	applog(LOG_DEBUG, "BFL: Attempting to open %s", devpath);
 
@@ -94,7 +121,7 @@ static bool bitforce_detect_one(const char *devpath)
 		return false;
 	}
 
-	bitforce_cmd1(fdDev, pdevbuf, sizeof(pdevbuf), "ZGX");
+	bitforce_cmd1(fdDev, 0, pdevbuf, sizeof(pdevbuf), "ZGX");
 	if (unlikely(!pdevbuf[0])) {
 		applog(LOG_DEBUG, "BFL: Error reading/timeout (ZGX)");
 		return 0;
@@ -107,7 +134,7 @@ static bool bitforce_detect_one(const char *devpath)
 	}
 
 	applog(LOG_DEBUG, "Found BitForce device on %s", devpath);
-	for ( bitforce_cmd1(fdDev, pdevbuf, sizeof(pdevbuf), "ZCX");
+	for ( bitforce_cmd1(fdDev, 0, pdevbuf, sizeof(pdevbuf), "ZCX");
 	      strncasecmp(pdevbuf, "OK", 2);
 	      BFgets(pdevbuf, sizeof(pdevbuf), fdDev) )
 	{
@@ -116,6 +143,8 @@ static bool bitforce_detect_one(const char *devpath)
 			continue;
 		pdevbuf[pdevbuf_len-1] = '\0';  // trim newline
 		applog(LOG_DEBUG, "  %s", pdevbuf);
+		if (!strncasecmp(pdevbuf, "DEVICES IN CHAIN:", 17))
+			procs = atoi(&pdevbuf[17]);
 	}
 	BFclose(fdDev);
 	
@@ -124,6 +153,7 @@ static bool bitforce_detect_one(const char *devpath)
 	bitforce->api = &bitforce_api;
 	bitforce->device_path = strdup(devpath);
 	bitforce->deven = DEV_ENABLED;
+	bitforce->procs = procs;
 	bitforce->threads = 1;
 
 	if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) {
@@ -256,7 +286,7 @@ void bitforce_init(struct cgpu_info *bitforce)
 	}
 
 	do {
-		bitforce_cmd1(fdDev, pdevbuf, sizeof(pdevbuf), "ZGX");
+		bitforce_cmd1(fdDev, 0, pdevbuf, sizeof(pdevbuf), "ZGX");
 		if (unlikely(!pdevbuf[0])) {
 			mutex_unlock(mutexp);
 			applog(LOG_ERR, "%s: Error reading/timeout (ZGX)", bitforce->dev_repr);
@@ -303,7 +333,7 @@ static void bitforce_flash_led(struct cgpu_info *bitforce)
 		return;
 
 	char pdevbuf[0x100];
-	bitforce_cmd1(fdDev, pdevbuf, sizeof(pdevbuf), "ZMX");
+	bitforce_cmd1(fdDev, bitforce->proc_id, pdevbuf, sizeof(pdevbuf), "ZMX");
 
 	/* Once we've tried - don't do it until told to again */
 	bitforce->flash_led = false;
@@ -343,7 +373,7 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
 	if (mutex_trylock(mutexp))
 		return false;
 
-	bitforce_cmd1(fdDev, pdevbuf, sizeof(pdevbuf), "ZLX");
+	bitforce_cmd1(fdDev, bitforce->proc_id, pdevbuf, sizeof(pdevbuf), "ZLX");
 	mutex_unlock(mutexp);
 	
 	if (unlikely(!pdevbuf[0])) {
@@ -452,9 +482,9 @@ void bitforce_job_start(struct thr_info *thr)
 re_send:
 	mutex_lock(mutexp);
 	if (bitforce->nonce_range)
-		bitforce_cmd2(fdDev, pdevbuf, sizeof(pdevbuf), "ZPX", ob, 68);
+		bitforce_cmd2(fdDev, bitforce->proc_id, pdevbuf, sizeof(pdevbuf), "ZPX", ob, 68);
 	else
-		bitforce_cmd2(fdDev, pdevbuf, sizeof(pdevbuf), "ZDX", ob, 60);
+		bitforce_cmd2(fdDev, bitforce->proc_id, pdevbuf, sizeof(pdevbuf), "ZDX", ob, 60);
 	if (!pdevbuf[0] || !strncasecmp(pdevbuf, "B", 1)) {
 		mutex_unlock(mutexp);
 		gettimeofday(&tv_now, NULL);
@@ -542,7 +572,7 @@ void bitforce_job_get_results(struct thr_info *thr, struct work *work)
 
 	while (1) {
 		mutex_lock(mutexp);
-		bitforce_cmd1(fdDev, pdevbuf, sizeof(data->noncebuf), "ZFX");
+		bitforce_cmd1(fdDev, bitforce->proc_id, pdevbuf, sizeof(data->noncebuf), "ZFX");
 		mutex_unlock(mutexp);
 
 		gettimeofday(&now, NULL);
@@ -693,17 +723,22 @@ static bool bitforce_thread_init(struct thr_info *thr)
 	unsigned int wait;
 	struct bitforce_data *data;
 	
-	bitforce->cgpu_data = data = malloc(sizeof(*data));
-	*data = (struct bitforce_data){
-		.next_work_ob = ">>>>>>>>|---------- MidState ----------||-DataTail-|>>>>>>>>>>>>>>>>",
-	};
-	bitforce->nonce_range = true;
-	bitforce->sleep_ms = BITFORCE_SLEEP_MS;
-	bitforce_change_mode(bitforce, false);
-	/* Initially enable support for nonce range and disable it later if it
-	 * fails */
-	if (opt_bfl_noncerange)
-		bitforce_change_mode(bitforce, true);
+	for ( ; bitforce; bitforce = bitforce->next_proc)
+	{
+		bitforce->cgpu_data = data = malloc(sizeof(*data));
+		*data = (struct bitforce_data){
+			.next_work_ob = ">>>>>>>>|---------- MidState ----------||-DataTail-|>>>>>>>>>>>>>>>>",
+		};
+		bitforce->nonce_range = true;
+		bitforce->sleep_ms = BITFORCE_SLEEP_MS;
+		bitforce_change_mode(bitforce, false);
+		/* Initially enable support for nonce range and disable it later if it
+		 * fails */
+		if (opt_bfl_noncerange)
+			bitforce_change_mode(bitforce, true);
+	}
+	
+	bitforce = thr->cgpu;
 
 	/* Pause each new thread at least 100ms between initialising
 	 * so the devices aren't making calls all at the same time. */