Commit da075689480fa4eae1d50ee9b71736a4952ad8aa

Con Kolivas 2013-11-10T19:19:18

Merge branch 'master' into nogpu

diff --git a/driver-bitfury.c b/driver-bitfury.c
index b177626..3331d82 100644
--- a/driver-bitfury.c
+++ b/driver-bitfury.c
@@ -224,13 +224,12 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 {
 	struct cgpu_info *bitfury = thr->cgpu;
 	struct bitfury_info *info = bitfury->device_data;
+	int amount, i, aged = 0, total = 0, ms_diff;
 	struct work *work, *tmp;
-	int amount, i, aged = 0;
 	struct timeval tv_now;
 	double nonce_rate;
 	int64_t ret = 0;
 	char buf[45];
-	int ms_diff;
 
 	work = get_queue_work(thr, bitfury, thr->id);
 	if (unlikely(thr->work_restart)) {
@@ -248,27 +247,28 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 	cgtime(&tv_now);
 	ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start);
 	if (ms_diff > 0) {
-		usb_read_timeout_cancellable(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES);
-		info->tot += amount;
+		usb_read_timeout_cancellable(bitfury, info->buf, 512, &amount, ms_diff,
+					     C_BF1_GETRES);
+		total += amount;
 	}
 
-	if (unlikely(thr->work_restart))
-		goto out;
-
 	/* Now look for the bulk of the previous work results, they will come
 	 * in a batch following the first data. */
 	cgtime(&tv_now);
 	ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start);
-	if (unlikely(ms_diff < 10))
+	/* If a work restart was sent, just empty the buffer. */
+	if (unlikely(ms_diff < 10 || thr->work_restart))
 		ms_diff = 10;
-	usb_read_once_timeout_cancellable(bitfury, info->buf + info->tot, BF1MSGSIZE,
+	usb_read_once_timeout_cancellable(bitfury, info->buf + total, BF1MSGSIZE,
 					  &amount, ms_diff, C_BF1_GETRES);
-	info->tot += amount;
+	total += amount;
 	while (amount) {
-		usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES);
-		info->tot += amount;
+		usb_read_once_timeout(bitfury, info->buf + total, 512, &amount, 10,
+				      C_BF1_GETRES);
+		total += amount;
 	};
 
+	/* Don't send whatever work we've stored if we got a restart */
 	if (unlikely(thr->work_restart))
 		goto out;
 
@@ -280,9 +280,10 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 	/* Get response acknowledging work */
 	usb_read(bitfury, buf, BF1MSGSIZE, &amount, C_BF1_GETWORK);
 
+out:
 	/* Search for what work the nonce matches in order of likelihood. Last
 	 * entry is end of result marker. */
-	for (i = 0; i < info->tot - BF1MSGSIZE; i += BF1MSGSIZE) {
+	for (i = 0; i < total - BF1MSGSIZE; i += BF1MSGSIZE) {
 		bool found = false;
 		uint32_t nonce;
 
@@ -304,8 +305,6 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
 			inc_hw_errors(thr);
 	}
 
-	info->tot = 0;
-out:
 	cgtime(&tv_now);
 
 	/* This iterates over the hashlist finding work started more than 6
diff --git a/driver-bitfury.h b/driver-bitfury.h
index 2f09de1..79921b8 100644
--- a/driver-bitfury.h
+++ b/driver-bitfury.h
@@ -19,7 +19,6 @@ struct bitfury_info {
 	char product[8];
 	uint32_t serial;
 	char buf[512];
-	int tot;
 	int nonces;
 	int total_nonces;
 	double saved_nonces;
diff --git a/driver-hashfast.c b/driver-hashfast.c
index 7549a83..281d2ea 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -128,14 +128,17 @@ static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t 
 	return true;
 }
 
-static bool hfa_send_header(struct cgpu_info *hashfast, struct hf_header *h, int cmd)
+/* Send an already assembled packet, consisting of an 8 byte header which may
+ * or may not be followed by a packet body. */
+
+static bool hfa_send_packet(struct cgpu_info *hashfast, struct hf_header *h, int cmd)
 {
 	int amount, ret, len;
 
-	len = sizeof(*h);
+	len = sizeof(*h) + h->data_length * 4;
 	ret = usb_write(hashfast, (char *)h, len, &amount, hfa_cmds[cmd].usb_cmd);
 	if (ret < 0 || amount != len) {
-		applog(LOG_WARNING, "HFA%d: send_header: %s USB Send error, ret %d amount %d vs. length %d",
+		applog(LOG_WARNING, "HFA%d: send_packet: %s USB Send error, ret %d amount %d vs. length %d",
 		       hashfast->device_id, hfa_cmds[cmd].cmd_name, ret, amount, len);
 		return false;
 	}
@@ -187,33 +190,57 @@ static bool hfa_get_data(struct cgpu_info *hashfast, char *buf, int len4)
 	return true;
 }
 
+static const char *hf_usb_init_errors[] = {
+	"Success",
+	"Reset timeout",
+	"Address cycle timeout",
+	"Clockgate operation timeout",
+	"Configuration operation timeout",
+	"Excessive core failures",
+	"All cores failed diagnostics",
+	"Too many groups configured - increase ntime roll amount"
+};
+
 static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
 {
 	struct hf_usb_init_header usb_init, *hu = &usb_init;
 	struct hf_usb_init_base *db;
+        struct hf_usb_init_options *ho;
 	char buf[1024];
 	struct hf_header *h = (struct hf_header *)buf;
 	uint8_t hcrc;
 	bool ret;
 	int i;
 
-	info->hash_clock_rate = 550;                        // Hash clock rate in Mhz
+        // XXX Following items need to be defaults with command-line overrides
+	info->hash_clock_rate = 550;	// Hash clock rate in Mhz
+	info->group_ntime_roll = 1;
+	info->core_ntime_roll = 1;
+
 	// Assemble the USB_INIT request
 	memset(hu, 0, sizeof(*hu));
 	hu->preamble = HF_PREAMBLE;
 	hu->operation_code = OP_USB_INIT;
-	hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE;          // Protocol to use
-	hu->hash_clock = info->hash_clock_rate;             // Hash clock rate in Mhz
+	hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE;	// Protocol to use
+	hu->hash_clock = info->hash_clock_rate;		// Hash clock rate in Mhz
+	if (info->group_ntime_roll > 1 && info->core_ntime_roll) {
+		ho = (struct hf_usb_init_options *)(hu + 1);
+		memset(ho, 0, sizeof(*ho));
+		ho->group_ntime_roll = info->group_ntime_roll;
+		ho->core_ntime_roll = info->core_ntime_roll;
+		hu->data_length = sizeof(*ho) / 4;
+	}
 	hu->crc8 = hfa_crc8((uint8_t *)hu);
 	applog(LOG_INFO, "HFA%d: Sending OP_USB_INIT with GWQ protocol specified",
 	       hashfast->device_id);
 
-	if (!hfa_send_header(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT)))
+	if (!hfa_send_packet(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT)))
 		return false;
 
 	// Check for the correct response.
 	// We extend the normal timeout - a complete device initialization, including
 	// bringing power supplies up from standby, etc., can take over a second.
+tryagain:
 	for (i = 0; i < 30; i++) {
 		ret = hfa_get_header(hashfast, h, &hcrc);
 		if (ret)
@@ -228,9 +255,12 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
 		return false;
 	}
 	if (h->operation_code != OP_USB_INIT) {
-		applog(LOG_WARNING, "HFA %d: OP_USB_INIT: Tossing packet, valid but unexpected type", hashfast->device_id);
+		// This can happen if valid packet(s) were in transit *before* the OP_USB_INIT arrived
+		// at the device, so we just toss the packets and keep looking for the response.
+		applog(LOG_WARNING, "HFA %d: OP_USB_INIT: Tossing packet, valid but unexpected type %d",
+                        hashfast->device_id, h->operation_code);
 		hfa_get_data(hashfast, buf, h->data_length);
-		return false;
+		goto tryagain;
 	}
 
 	applog(LOG_DEBUG, "HFA %d: Good reply to OP_USB_INIT", hashfast->device_id);
@@ -241,7 +271,7 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
 	info->asic_count = h->chip_address;
 	info->core_count = h->core_address;
 	info->device_type = (uint8_t)h->hdata;
-	info->ref_frequency = (uint8_t)(h->hdata>>8);
+	info->ref_frequency = (uint8_t)(h->hdata >> 8);
 	info->hash_sequence_head = 0;
 	info->hash_sequence_tail = 0;
 	info->device_sequence_tail = 0;
@@ -286,6 +316,15 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
 		return false;
 	}
 
+	// See if the initialization suceeded
+	if (db->operation_status) {
+		applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Operation status %d (%s)",
+			hashfast->device_id, db->operation_status,
+			(db->operation_status < sizeof(hf_usb_init_errors)/sizeof(hf_usb_init_errors[0])) ?
+			hf_usb_init_errors[db->operation_status] : "Unknown error code");
+		return false;
+	}
+
 	return true;
 }
 
diff --git a/driver-hashfast.h b/driver-hashfast.h
index 6c8efb2..cf6b7ad 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -79,6 +79,8 @@ struct hashfast_info {
 	struct hf_config_data config_data;          // Configuration data used from USB_INIT
 	int core_bitmap_size;                       // in bytes
 	uint32_t *core_bitmap;                      // Core OK bitmap test results, run with PLL Bypassed
+	int group_ntime_roll;                       // Total ntime roll amount per group
+	int core_ntime_roll;                        // Total core ntime roll amount
 
 	pthread_mutex_t lock;
 	struct work **works;
diff --git a/driver-klondike.c b/driver-klondike.c
index a445bf4..2446202 100644
--- a/driver-klondike.c
+++ b/driver-klondike.c
@@ -1432,7 +1432,8 @@ static void get_klondike_statline_before(char *buf, size_t siz, struct cgpu_info
 	}
 	rd_unlock(&(klninfo->stat_lock));
 	fan /= slaves + 1;
-	fan *= 100/255;
+	//fan *= 100/255; // <-- You can't do this because int 100 / int 255 == 0
+        fan = 100 * fan / 255;
 	if (fan > 99) // short on screen space
 		fan = 99;
 	clock /= slaves + 1;
diff --git a/sha2.c b/sha2.c
index f1970e1..6777b28 100644
--- a/sha2.c
+++ b/sha2.c
@@ -36,16 +36,6 @@
 
 #include "sha2.h"
 
-#define SHFR(x, n)    (x >> n)
-#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
-#define CH(x, y, z)  ((x & y) ^ (~x & z))
-#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
-
-#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
-#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
-#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
-#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
-
 #define UNPACK32(x, str)                      \
 {                                             \
     *((str) + 3) = (uint8_t) ((x)      );       \
diff --git a/sha2.h b/sha2.h
index faa4f61..71d4404 100644
--- a/sha2.h
+++ b/sha2.h
@@ -41,6 +41,16 @@
 #define SHA256_DIGEST_SIZE ( 256 / 8)
 #define SHA256_BLOCK_SIZE  ( 512 / 8)
 
+#define SHFR(x, n)    (x >> n)
+#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
+#define CH(x, y, z)  ((x & y) ^ (~x & z))
+#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
+
+#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
+#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
+#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
+#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))
+
 typedef struct {
     unsigned int tot_len;
     unsigned int len;
@@ -48,6 +58,8 @@ typedef struct {
     uint32_t h[8];
 } sha256_ctx;
 
+extern uint32_t sha256_k[64];
+
 void sha256_init(sha256_ctx * ctx);
 void sha256_update(sha256_ctx *ctx, const unsigned char *message,
                    unsigned int len);
diff --git a/usbutils.c b/usbutils.c
index 3b62545..c36aeac 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -2442,7 +2442,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
 
 	if (length > usb_epinfo->wMaxPacketSize)
 		length = usb_epinfo->wMaxPacketSize;
-	else if (length == usb_epinfo->wMaxPacketSize)
+	else
 		eot = true;
 
 	/* Avoid any async transfers during shutdown to allow the polling
@@ -2456,7 +2456,9 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
 		memcpy(buf, data, length);
 		/* If this is the last packet in a transfer and is the length
 		 * of the wMaxPacketSize then we need to send a zero length
-		 * packet to let the device know it's the end of the message.*/
+		 * packet to let the device know it's the end of the message.
+		 * Since libusb may batch transfers together, we send a zlp at
+		 * the end of every transfer on windows just in case. */
 		if (eot)
 			zlp = true;
 #ifndef WIN32