|
|
@ -199,50 +199,60 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cgpu_info *bitfury = thr->cgpu; |
|
|
|
struct cgpu_info *bitfury = thr->cgpu; |
|
|
|
struct bitfury_info *info = bitfury->device_data; |
|
|
|
struct bitfury_info *info = bitfury->device_data; |
|
|
|
char sendbuf[45], buf[512]; |
|
|
|
|
|
|
|
int64_t hashes = 0; |
|
|
|
int64_t hashes = 0; |
|
|
|
int amount, i, tot; |
|
|
|
char buf[45]; |
|
|
|
|
|
|
|
int amount, i; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf[0] = 'W'; |
|
|
|
|
|
|
|
memcpy(buf + 1, work->midstate, 32); |
|
|
|
|
|
|
|
memcpy(buf + 33, work->data + 64, 12); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* New results may spill out from the latest work, making us drop out
|
|
|
|
|
|
|
|
* too early so read whatever we get for the first half nonce and then |
|
|
|
|
|
|
|
* look for the results to prev work. */ |
|
|
|
|
|
|
|
usb_read_timeout(bitfury, info->buf, 512, &info->tot, 600, C_BFO_GETRES); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Now look for the bulk of the previous work results, they will come
|
|
|
|
|
|
|
|
* in a batch following the first data. */ |
|
|
|
|
|
|
|
usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, 1000, C_BFO_GETRES); |
|
|
|
|
|
|
|
info->tot += amount; |
|
|
|
|
|
|
|
while (amount) { |
|
|
|
|
|
|
|
usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BFO_GETRES); |
|
|
|
|
|
|
|
info->tot += amount; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
sendbuf[0] = 'W'; |
|
|
|
/* Send work */ |
|
|
|
memcpy(sendbuf + 1, work->midstate, 32); |
|
|
|
usb_write(bitfury, buf, 45, &amount, C_BFO_REQWORK); |
|
|
|
memcpy(sendbuf + 33, work->data + 64, 12); |
|
|
|
/* Get response acknowledging work */ |
|
|
|
usb_write(bitfury, sendbuf, 45, &amount, C_BFO_REQWORK); |
|
|
|
|
|
|
|
usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); |
|
|
|
usb_read(bitfury, buf, 7, &amount, C_BFO_GETWORK); |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(!info->prevwork1)) { |
|
|
|
/* Only happens on startup */ |
|
|
|
info->prevwork1 = copy_work(work); |
|
|
|
if (unlikely(!info->prevwork2)) |
|
|
|
info->prevwork2 = copy_work(work); |
|
|
|
goto cascade; |
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
usb_read_once_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BFO_GETRES); |
|
|
|
/* Search for what work the nonce matches in order of likelihood. */ |
|
|
|
tot = amount; |
|
|
|
for (i = 0; i < info->tot; i += 7) { |
|
|
|
while (amount) { |
|
|
|
|
|
|
|
usb_read_once_timeout(bitfury, buf + tot, 512, &amount, 10, C_BFO_GETRES); |
|
|
|
|
|
|
|
tot += amount; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < tot; i += 7) { |
|
|
|
|
|
|
|
uint32_t nonce; |
|
|
|
uint32_t nonce; |
|
|
|
|
|
|
|
|
|
|
|
/* Ignore state & switched data in results for now. */ |
|
|
|
/* Ignore state & switched data in results for now. */ |
|
|
|
memcpy(&nonce, buf + i + 3, 4); |
|
|
|
memcpy(&nonce, info->buf + i + 3, 4); |
|
|
|
nonce = decnonce(nonce); |
|
|
|
nonce = decnonce(nonce); |
|
|
|
if (bitfury_checkresults(thr, info->prevwork1, nonce)) { |
|
|
|
if (bitfury_checkresults(thr, info->prevwork1, nonce)) { |
|
|
|
hashes += 0xffffffff; |
|
|
|
hashes += 0xffffffff; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (bitfury_checkresults(thr, work, nonce)) { |
|
|
|
if (bitfury_checkresults(thr, info->prevwork2, nonce)) { |
|
|
|
hashes += 0xffffffff; |
|
|
|
hashes += 0xffffffff; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
if (bitfury_checkresults(thr, info->prevwork2, nonce)) { |
|
|
|
if (bitfury_checkresults(thr, work, nonce)) { |
|
|
|
hashes += 0xffffffff; |
|
|
|
hashes += 0xffffffff; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
free_work(info->prevwork2); |
|
|
|
free_work(info->prevwork2); |
|
|
|
|
|
|
|
cascade: |
|
|
|
info->prevwork2 = info->prevwork1; |
|
|
|
info->prevwork2 = info->prevwork1; |
|
|
|
info->prevwork1 = copy_work(work); |
|
|
|
info->prevwork1 = copy_work(work); |
|
|
|
work->blk.nonce = 0xffffffff; |
|
|
|
work->blk.nonce = 0xffffffff; |
|
|
|