|
|
|
@ -15,6 +15,7 @@
@@ -15,6 +15,7 @@
|
|
|
|
|
|
|
|
|
|
/* Wait longer 1/3 longer than it would take for a full nonce range */ |
|
|
|
|
#define BF1WAIT 1600 |
|
|
|
|
#define BF1MSGSIZE 7 |
|
|
|
|
|
|
|
|
|
static void bitfury_empty_buffer(struct cgpu_info *bitfury) |
|
|
|
|
{ |
|
|
|
@ -26,18 +27,29 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury)
@@ -26,18 +27,29 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury)
|
|
|
|
|
} while (amount); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void bitfury_open(struct cgpu_info *bitfury) |
|
|
|
|
static int bitfury_open(struct cgpu_info *bitfury) |
|
|
|
|
{ |
|
|
|
|
uint32_t buf[2]; |
|
|
|
|
int err; |
|
|
|
|
|
|
|
|
|
bitfury_empty_buffer(bitfury); |
|
|
|
|
/* Magic sequence to reset device only really needed for windows but
|
|
|
|
|
* harmless on linux. */ |
|
|
|
|
buf[0] = 0x80250000; |
|
|
|
|
buf[1] = 0x00000800; |
|
|
|
|
usb_transfer(bitfury, 0, 9, 1, 0, C_BF1_RESET); |
|
|
|
|
usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_OPEN); |
|
|
|
|
usb_transfer_data(bitfury, 0x21, 0x20, 0x0000, 0, buf, 7, C_BF1_INIT); |
|
|
|
|
err = usb_transfer(bitfury, 0, 9, 1, 0, C_BF1_RESET); |
|
|
|
|
if (!err) |
|
|
|
|
err = usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_OPEN); |
|
|
|
|
if (!err) { |
|
|
|
|
err = usb_transfer_data(bitfury, 0x21, 0x20, 0x0000, 0, buf, |
|
|
|
|
BF1MSGSIZE, C_BF1_INIT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (err < 0) { |
|
|
|
|
applog(LOG_INFO, "%s %d: Failed to open with error %s", bitfury->drv->name, |
|
|
|
|
bitfury->device_id, libusb_error_name(err)); |
|
|
|
|
} |
|
|
|
|
return (err == BF1MSGSIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void bitfury_close(struct cgpu_info *bitfury) |
|
|
|
@ -95,15 +107,16 @@ static bool bitfury_reset(struct cgpu_info *bitfury)
@@ -95,15 +107,16 @@ static bool bitfury_reset(struct cgpu_info *bitfury)
|
|
|
|
|
bitfury->drv->name, bitfury->device_id); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
err = usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET); |
|
|
|
|
err = usb_read_timeout(bitfury, buf, BF1MSGSIZE, &amount, BF1WAIT, |
|
|
|
|
C_BF1_GETRESET); |
|
|
|
|
if (err) { |
|
|
|
|
applog(LOG_INFO, "%s %d: Failed to read GETRESET", |
|
|
|
|
bitfury->drv->name, bitfury->device_id); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (amount != 7) { |
|
|
|
|
applog(LOG_INFO, "%s %d: Getreset received %d bytes instead of 7", |
|
|
|
|
bitfury->drv->name, bitfury->device_id, amount); |
|
|
|
|
if (amount != BF1MSGSIZE) { |
|
|
|
|
applog(LOG_INFO, "%s %d: Getreset received %d bytes instead of %d", |
|
|
|
|
bitfury->drv->name, bitfury->device_id, amount, BF1MSGSIZE); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
applog(LOG_DEBUG, "%s %d: Getreset returned %s", bitfury->drv->name, |
|
|
|
@ -131,7 +144,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device
@@ -131,7 +144,8 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device
|
|
|
|
|
|
|
|
|
|
usb_buffer_enable(bitfury); |
|
|
|
|
|
|
|
|
|
bitfury_open(bitfury); |
|
|
|
|
if (!bitfury_open(bitfury)) |
|
|
|
|
goto out_close; |
|
|
|
|
|
|
|
|
|
/* Send getinfo request */ |
|
|
|
|
if (!bitfury_getinfo(bitfury, info)) |
|
|
|
@ -235,7 +249,8 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
@@ -235,7 +249,8 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
|
|
|
|
|
ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start); |
|
|
|
|
if (unlikely(ms_diff < 10)) |
|
|
|
|
ms_diff = 10; |
|
|
|
|
usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES); |
|
|
|
|
usb_read_once_timeout(bitfury, info->buf + info->tot, BF1MSGSIZE, |
|
|
|
|
&amount, ms_diff, C_BF1_GETRES); |
|
|
|
|
info->tot += amount; |
|
|
|
|
while (amount) { |
|
|
|
|
usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); |
|
|
|
@ -249,7 +264,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
@@ -249,7 +264,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
|
|
|
|
|
usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK); |
|
|
|
|
cgtime(&info->tv_start); |
|
|
|
|
/* Get response acknowledging work */ |
|
|
|
|
usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK); |
|
|
|
|
usb_read(bitfury, buf, BF1MSGSIZE, &amount, C_BF1_GETWORK); |
|
|
|
|
|
|
|
|
|
/* Only happens on startup */ |
|
|
|
|
if (unlikely(!info->prevwork[BF1ARRAY_SIZE])) |
|
|
|
@ -257,7 +272,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
@@ -257,7 +272,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
|
|
|
|
|
|
|
|
|
|
/* Search for what work the nonce matches in order of likelihood. Last
|
|
|
|
|
* entry is end of result marker. */ |
|
|
|
|
for (i = 0; i < info->tot - 7; i += 7) { |
|
|
|
|
for (i = 0; i < info->tot - BF1MSGSIZE; i += BF1MSGSIZE) { |
|
|
|
|
uint32_t nonce; |
|
|
|
|
int j; |
|
|
|
|
|
|
|
|
|