Browse Source

bitmain: Support for talking to a device over the network

Luke Dashjr 10 years ago
parent
commit
61ef6e6f1e
2 changed files with 84 additions and 0 deletions
  1. 80 0
      driver-bitmain.c
  2. 4 0
      driver-bitmain.h

+ 80 - 0
driver-bitmain.c

@@ -32,6 +32,7 @@
   #include <io.h>
 #endif
 
+#include <curl/curl.h>
 #include <uthash.h>
 
 #include "deviceapi.h"
@@ -52,6 +53,8 @@ static inline unsigned int bfg_work_block(struct work * const work)
 
 #define htole8(x) (x)
 
+#define BITMAIN_USING_CURL  -2
+
 static
 struct cgpu_info *btm_alloc_cgpu(struct device_drv *drv, int threads)
 {
@@ -95,6 +98,25 @@ bool btm_init(struct cgpu_info *cgpu, const char * devpath)
 		return false;
 	}
 	struct bitmain_info *info = cgpu->device_data;
+	if (!strncmp(devpath, "ip:", 3)) {
+		CURL *curl = curl_easy_init();
+		if (!curl)
+			applogr(false, LOG_ERR, "%s: curl_easy_init failed", cgpu->drv->dname);
+		curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
+		curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5);
+		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
+		curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
+		curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1);
+		curl_easy_setopt(curl, CURLOPT_URL, &devpath[3]);
+		if (curl_easy_perform(curl)) {
+			curl_easy_cleanup(curl);
+			applogr(false, LOG_ERR, "%s: curl_easy_perform failed for %s", cgpu->drv->dname, &devpath[3]);
+		}
+		cgpu->device_path = strdup(devpath);
+		cgpu->device_fd = BITMAIN_USING_CURL;
+		info->device_curl = curl;
+		return true;
+	}
 	fd = serial_open(devpath, info->baud, 1, true);
 	if(fd == -1) {
 		applog(LOG_DEBUG, "%s open %s error %d",
@@ -110,6 +132,8 @@ bool btm_init(struct cgpu_info *cgpu, const char * devpath)
 static
 void btm_uninit(struct cgpu_info *cgpu)
 {
+	struct bitmain_info * const info = cgpu->device_data;
+	
 	applog(LOG_DEBUG, "BTM uninit %s%i", cgpu->drv->name, cgpu->device_fd);
 
 	// May have happened already during a failed initialisation
@@ -118,17 +142,58 @@ void btm_uninit(struct cgpu_info *cgpu)
 		serial_close(cgpu->device_fd);
 		cgpu->device_fd = -1;
 	}
+	if (info->device_curl) {
+		curl_easy_cleanup(info->device_curl);
+		info->device_curl = NULL;
+	}
 	if(cgpu->device_path) {
 		free((char*)cgpu->device_path);
 		cgpu->device_path = NULL;
 	}
 }
 
+bool bitmain_curl_all(void *func_p, CURL * const curl, void *p, size_t remsz)
+{
+	CURLcode (*func)(CURL *, void *, size_t, size_t *) = func_p;
+	CURLcode r;
+	size_t sz;
+	while (remsz) {
+		r = func(curl, p, remsz, &sz);
+		switch (r) {
+			case CURLE_OK:
+				remsz -= sz;
+				p += sz;
+				break;
+			case CURLE_AGAIN:
+				break;
+			default:
+				return false;
+		}
+	}
+	return true;
+}
+
 static
 int btm_read(struct cgpu_info * const cgpu, void * const buf, const size_t bufsize)
 {
 	int err = 0;
 	//applog(LOG_DEBUG, "btm_read ----- %d -----", bufsize);
+	if (unlikely(cgpu->device_fd == BITMAIN_USING_CURL)) {
+		struct bitmain_info * const info = cgpu->device_data;
+		uint8_t headbuf[5];
+		headbuf[0] = 0;
+		pk_u32be(headbuf, 1, bufsize);
+		if (!bitmain_curl_all(curl_easy_send, info->device_curl, headbuf, sizeof(headbuf)))
+			return -1;
+		if (!bitmain_curl_all(curl_easy_recv, info->device_curl, headbuf, 4))
+			return -1;
+		if (headbuf[0] == 0xff && headbuf[1] == 0xff && headbuf[2] == 0xff && headbuf[3] == 0xff)
+			return -1;
+		size_t sz = upk_u32be(headbuf, 0);
+		if (!bitmain_curl_all(curl_easy_recv, info->device_curl, buf, sz))
+			return -1;
+		return sz;
+	}
 	err = read(cgpu->device_fd, buf, bufsize);
 	return err;
 }
@@ -138,6 +203,21 @@ int btm_write(struct cgpu_info * const cgpu, void * const buf, const size_t bufs
 {
 	int err = 0;
 	//applog(LOG_DEBUG, "btm_write ----- %d -----", bufsize);
+	if (unlikely(cgpu->device_fd == BITMAIN_USING_CURL)) {
+		struct bitmain_info * const info = cgpu->device_data;
+		uint8_t headbuf[5];
+		headbuf[0] = 1;
+		pk_u32be(headbuf, 1, bufsize);
+		if (!bitmain_curl_all(curl_easy_send, info->device_curl, headbuf, sizeof(headbuf)))
+			return -1;
+		if (!bitmain_curl_all(curl_easy_send, info->device_curl, buf, bufsize))
+			return -1;
+		if (!bitmain_curl_all(curl_easy_recv, info->device_curl, headbuf, 4))
+			return -1;
+		if (headbuf[0] == 0xff && headbuf[1] == 0xff && headbuf[2] == 0xff && headbuf[3] == 0xff)
+			return -1;
+		return upk_u32be(headbuf, 0);
+	}
 	err = write(cgpu->device_fd, buf, bufsize);
 	return err;
 }

+ 4 - 0
driver-bitmain.h

@@ -13,6 +13,8 @@
 
 #ifdef USE_BITMAIN
 
+#include <curl/curl.h>
+
 #include "util.h"
 
 //#define BITMAIN_TYPE_S1
@@ -227,6 +229,8 @@ struct bitmain_rxnonce_data {
 } __attribute__((packed, aligned(4)));
 
 struct bitmain_info {
+	void *device_curl;
+	
 	int baud;
 	int chain_num;
 	int asic_num;