@ -11,7 +11,10 @@
@@ -11,7 +11,10 @@
# include "miner.h"
# include "driver-bitfury.h"
# include "sha2.h"
/* Wait longer 1/3 longer than it would take for a full nonce range */
# define BF1WAIT 1600
struct device_drv bitfury_drv ;
static void bitfury_empty_buffer ( struct cgpu_info * bitfury )
@ -27,16 +30,17 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury)
@@ -27,16 +30,17 @@ static void bitfury_empty_buffer(struct cgpu_info *bitfury)
static void bitfury_open ( struct cgpu_info * bitfury )
{
/* Magic open sequence */
usb_transfer ( bitfury , 0x21 , 0x22 , 0x0003 , 0 , C_BFO _OPEN ) ;
usb_transfer ( bitfury , 0x21 , 0x22 , 0x0003 , 0 , C_BF1 _OPEN ) ;
bitfury_empty_buffer ( bitfury ) ;
}
static void bitfury_close ( struct cgpu_info * bitfury )
{
bitfury_empty_buffer ( bitfury ) ;
/* Magic close sequence */
usb_transfer ( bitfury , 0x21 , 0x22 , 0 , 0 , C_BFO _CLOSE ) ;
usb_transfer ( bitfury , 0x21 , 0x22 , 0 , 0 , C_BF1 _CLOSE ) ;
bitfury_empty_buffer ( bitfury ) ;
usb_transfer ( bitfury , 0x23 , 0x08 , 0x9053 , 1 , C_BFO _CLOSE ) ;
usb_transfer ( bitfury , 0x23 , 0x08 , 0x9053 , 1 , C_BF1 _CLOSE ) ;
bitfury_empty_buffer ( bitfury ) ;
}
@ -47,12 +51,51 @@ static void bitfury_identify(struct cgpu_info *bitfury)
@@ -47,12 +51,51 @@ static void bitfury_identify(struct cgpu_info *bitfury)
usb_write ( bitfury , " L " , 1 , & amount , C_PING ) ;
}
static bool bitfury_getinfo ( struct cgpu_info * bitfury , struct bitfury_info * info )
{
char buf [ 512 ] ;
int amount ;
usb_write ( bitfury , " I " , 1 , & amount , C_BF1_REQINFO ) ;
usb_read ( bitfury , buf , 14 , & amount , C_BF1_GETINFO ) ;
if ( amount ! = 14 ) {
applog ( LOG_INFO , " %s %d: Getinfo received %d bytes " ,
bitfury - > drv - > name , bitfury - > device_id , amount ) ;
return false ;
}
info - > version = buf [ 1 ] ;
memcpy ( & info - > product , buf + 2 , 8 ) ;
memcpy ( & info - > serial , buf + 10 , 4 ) ;
applog ( LOG_INFO , " %s %d: Getinfo returned version %d, product %s serial %08x " , bitfury - > drv - > name ,
bitfury - > device_id , info - > version , info - > product , info - > serial ) ;
bitfury_empty_buffer ( bitfury ) ;
return true ;
}
static bool bitfury_reset ( struct cgpu_info * bitfury )
{
char buf [ 512 ] ;
int amount ;
usb_write ( bitfury , " R " , 1 , & amount , C_BF1_REQRESET ) ;
usb_read_timeout ( bitfury , buf , 7 , & amount , BF1WAIT , C_BF1_GETRESET ) ;
if ( amount ! = 7 ) {
applog ( LOG_INFO , " %s %d: Getreset received %d bytes " ,
bitfury - > drv - > name , bitfury - > device_id , amount ) ;
return false ;
}
applog ( LOG_INFO , " %s %d: Getreset returned %s " , bitfury - > drv - > name ,
bitfury - > device_id , buf ) ;
bitfury_empty_buffer ( bitfury ) ;
return true ;
}
static bool bitfury_detect_one ( struct libusb_device * dev , struct usb_find_devices * found )
{
struct cgpu_info * bitfury ;
struct bitfury_info * info ;
char buf [ 512 ] ;
int amount ;
bitfury = usb_alloc_cgpu ( & bitfury_drv , 1 ) ;
@ -73,37 +116,23 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device
@@ -73,37 +116,23 @@ static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_device
bitfury_open ( bitfury ) ;
/* Send getinfo request */
usb_write ( bitfury , " I " , 1 , & amount , C_BFO_REQINFO ) ;
usb_read ( bitfury , buf , 14 , & amount , C_BFO_GETINFO ) ;
if ( amount ! = 14 ) {
applog ( LOG_WARNING , " %s%d: Getinfo received %d bytes " ,
bitfury - > drv - > name , bitfury - > device_id , amount ) ;
if ( ! bitfury_getinfo ( bitfury , info ) )
goto out_close ;
}
info - > version = buf [ 1 ] ;
memcpy ( & info - > product , buf + 2 , 8 ) ;
memcpy ( & info - > serial , buf + 10 , 4 ) ;
applog ( LOG_INFO , " %s%d: Getinfo returned version %d, product %s serial %08x " , bitfury - > drv - > name ,
bitfury - > device_id , info - > version , info - > product , info - > serial ) ;
bitfury_empty_buffer ( bitfury ) ;
/* Send reset request */
usb_write ( bitfury , " R " , 1 , & amount , C_BFO_REQRESET ) ;
usb_read_timeout ( bitfury , buf , 7 , & amount , 1000 , C_BFO_GETRESET ) ;
if ( amount ! = 7 ) {
applog ( LOG_WARNING , " %s%d: Getreset received %d bytes " ,
bitfury - > drv - > name , bitfury - > device_id , amount ) ;
if ( ! bitfury_reset ( bitfury ) )
goto out_close ;
}
applog ( LOG_INFO , " %s%d: Getreset returned %s " , bitfury - > drv - > name ,
bitfury - > device_id , buf ) ;
bitfury_empty_buffer ( bitfury ) ;
bitfury_identify ( bitfury ) ;
bitfury_empty_buffer ( bitfury ) ;
//return true;
if ( ! add_cgpu ( bitfury ) )
goto out_close ;
update_usb_stats ( bitfury ) ;
applog ( LOG_INFO , " %s %d: Found at %s " ,
bitfury - > drv - > name , bitfury - > device_id , bitfury - > device_path ) ;
return true ;
out_close :
bitfury_close ( bitfury ) ;
out :
@ -115,40 +144,152 @@ static void bitfury_detect(void)
@@ -115,40 +144,152 @@ static void bitfury_detect(void)
usb_detect ( & bitfury_drv , bitfury_detect_one ) ;
}
static bool bitfury_prepare ( struct thr_info __maybe_unused * thr )
static uint32_t decnonce ( uint32_t in )
{
return false ;
uint32_t out ;
/* First part load */
out = ( in & 0xFF ) < < 24 ; in > > = 8 ;
/* Byte reversal */
in = ( ( ( in & 0xaaaaaaaa ) > > 1 ) | ( ( in & 0x55555555 ) < < 1 ) ) ;
in = ( ( ( in & 0xcccccccc ) > > 2 ) | ( ( in & 0x33333333 ) < < 2 ) ) ;
in = ( ( ( in & 0xf0f0f0f0 ) > > 4 ) | ( ( in & 0x0f0f0f0f ) < < 4 ) ) ;
out | = ( in > > 2 ) & 0x3FFFFF ;
/* Extraction */
if ( in & 1 ) out | = ( 1 < < 23 ) ;
if ( in & 2 ) out | = ( 1 < < 22 ) ;
out - = 0x800004 ;
return out ;
}
static bool bitfury_fill ( struct cgpu_info __maybe_unused * bitfury )
# define BT_OFFSETS 3
const uint32_t bf_offsets [ ] = { 0 , - 0x400000 , - 0x800000 } ;
static bool bitfury_checkresults ( struct thr_info * thr , struct work * work , uint32_t nonce )
{
int i ;
for ( i = 0 ; i < BT_OFFSETS ; i + + ) {
if ( test_nonce ( work , nonce + bf_offsets [ i ] ) ) {
submit_tested_work ( thr , work ) ;
return true ;
}
}
return false ;
}
static int64_t bitfury_scanhash ( struct thr_info __maybe_unused * thr )
static int64_t bitfury_scanhash ( struct thr_info * thr , struct work * work ,
int64_t __maybe_unused max_nonce )
{
return 0 ;
struct cgpu_info * bitfury = thr - > cgpu ;
struct bitfury_info * info = bitfury - > device_data ;
struct timeval tv_now ;
int amount , i ;
char buf [ 45 ] ;
int ms_diff ;
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 . */
cgtime ( & tv_now ) ;
ms_diff = 600 - ms_tdiff ( & tv_now , & info - > tv_start ) ;
if ( ms_diff > 0 ) {
usb_read_timeout ( bitfury , info - > buf , 512 , & amount , ms_diff , C_BF1_GETRES ) ;
info - > tot + = amount ;
}
static void bitfury_flush_work ( struct cgpu_info __maybe_unused * bitfury )
{
if ( unlikely ( thr - > work_restart ) )
goto cascade ;
/* 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 ) )
ms_diff = 10 ;
usb_read_once_timeout ( bitfury , info - > buf + info - > tot , 7 , & 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 ) ;
info - > tot + = amount ;
} ;
if ( unlikely ( thr - > work_restart ) )
goto cascade ;
/* Send 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 ) ;
/* Only happens on startup */
if ( unlikely ( ! info - > prevwork [ BF1ARRAY_SIZE ] ) )
goto cascade ;
/* 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 ) {
uint32_t nonce ;
int j ;
/* Ignore state & switched data in results for now. */
memcpy ( & nonce , info - > buf + i + 3 , 4 ) ;
nonce = decnonce ( nonce ) ;
for ( j = 0 ; j < BF1ARRAY_SIZE ; j + + ) {
if ( bitfury_checkresults ( thr , info - > prevwork [ j ] , nonce ) ) {
info - > nonces + + ;
break ;
}
}
}
static struct api_data * bitfury_api_stats ( struct cgpu_info __maybe_unused * cgpu )
{
return NULL ;
info - > tot = 0 ;
free_work ( info - > prevwork [ BF1ARRAY_SIZE ] ) ;
cascade :
for ( i = BF1ARRAY_SIZE ; i > 0 ; i - - )
info - > prevwork [ i ] = info - > prevwork [ i - 1 ] ;
info - > prevwork [ 0 ] = copy_work ( work ) ;
work - > blk . nonce = 0xffffffff ;
if ( info - > nonces ) {
info - > nonces - - ;
return ( int64_t ) 0xffffffff ;
}
return 0 ;
}
static void get_bitfury_statline_before ( char __maybe_unused * buf , size_t __maybe_unused bufsiz ,
struct cgpu_info __maybe_unused * bitfury )
static struct api_data * bitfury_api_stats ( struct cgpu_info * cgpu )
{
struct bitfury_info * info = cgpu - > device_data ;
struct api_data * root = NULL ;
char serial [ 16 ] ;
int version ;
version = info - > version ;
root = api_add_int ( root , " Version " , & version , true ) ;
root = api_add_string ( root , " Product " , info - > product , false ) ;
sprintf ( serial , " %08x " , info - > serial ) ;
root = api_add_string ( root , " Serial " , serial , true ) ;
return root ;
}
static void bitfury_init ( struct cgpu_info __maybe_unused * bitfury )
static void bitfury_init ( struct cgpu_info * bitfury )
{
bitfury_close ( bitfury ) ;
bitfury_open ( bitfury ) ;
bitfury_reset ( bitfury ) ;
}
static void bitfury_shutdown ( struct thr_info __maybe_unused * thr )
static void bitfury_shutdown ( struct thr_info * thr )
{
struct cgpu_info * bitfury = thr - > cgpu ;
@ -159,15 +300,10 @@ static void bitfury_shutdown(struct thr_info __maybe_unused *thr)
@@ -159,15 +300,10 @@ static void bitfury_shutdown(struct thr_info __maybe_unused *thr)
struct device_drv bitfury_drv = {
. drv_id = DRIVER_BITFURY ,
. dname = " bitfury " ,
. name = " BFO " ,
. name = " BF1 " ,
. drv_detect = bitfury_detect ,
. thread_prepare = bitfury_prepare ,
. hash_work = hash_queued_work ,
. queue_full = bitfury_fill ,
. scanwork = bitfury_scanhash ,
. flush_work = bitfury_flush_work ,
. scanhash = bitfury_scanhash ,
. get_api_stats = bitfury_api_stats ,
. get_statline_before = get_bitfury_statline_before ,
. reinit_device = bitfury_init ,
. thread_shutdown = bitfury_shutdown ,
. identify_device = bitfury_identify