Merge branch 'master' into nogpu
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
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