@ -1,4 +1,5 @@
@@ -1,4 +1,5 @@
/*
* Copyright 2012 - 2013 Andrew Smith
* Copyright 2012 Luke Dashjr
* Copyright 2012 Con Kolivas
*
@ -19,34 +20,35 @@
@@ -19,34 +20,35 @@
# include "config.h"
# ifdef WIN32
# include <windows.h>
# define dlsym (void*)GetProcAddress
# define dlclose FreeLibrary
typedef unsigned long FT_STATUS ;
typedef PVOID FT_HANDLE ;
__stdcall FT_STATUS ( * FT_ListDevices ) ( PVOID pArg1 , PVOID pArg2 , DWORD Flags ) ;
__stdcall FT_STATUS ( * FT_Open ) ( int idx , FT_HANDLE * ) ;
__stdcall FT_STATUS ( * FT_GetComPortNumber ) ( FT_HANDLE , LPLONG lplComPortNumber ) ;
__stdcall FT_STATUS ( * FT_Close ) ( FT_HANDLE ) ;
const uint32_t FT_OPEN_BY_DESCRIPTION = 2 ;
const uint32_t FT_LIST_ALL = 0x20000000 ;
const uint32_t FT_LIST_NUMBER_ONLY = 0x80000000 ;
enum {
FT_OK ,
} ;
// Code must deal with a timeout. Make it 1 second on windows, 0.1 on linux.
# define BFopen(devpath) serial_open(devpath, 0, 10, true)
# else /* WIN32 */
# define BFopen(devpath) serial_open(devpath, 0, 1, true)
# endif /* WIN32 */
# include "compat.h"
# include "miner.h"
# include "fpgautils.h"
# include "usbutils.h"
# define BITFORCE_IDENTIFY "ZGX"
# define BITFORCE_IDENTIFY_LEN (sizeof(BITFORCE_IDENTIFY)-1)
# define BITFORCE_FLASH "ZMX"
# define BITFORCE_FLASH_LEN (sizeof(BITFORCE_FLASH)-1)
# define BITFORCE_TEMPERATURE "ZLX"
# define BITFORCE_TEMPERATURE_LEN (sizeof(BITFORCE_TEMPERATURE)-1)
# define BITFORCE_SENDRANGE "ZPX"
# define BITFORCE_SENDRANGE_LEN (sizeof(BITFORCE_SENDRANGE)-1)
# define BITFORCE_SENDWORK "ZDX"
# define BITFORCE_SENDWORK_LEN (sizeof(BITFORCE_SENDWORK)-1)
# define BITFORCE_WORKSTATUS "ZFX"
# define BITFORCE_WORKSTATUS_LEN (sizeof(BITFORCE_WORKSTATUS)-1)
// Either of Nonce or No-nonce start with:
# define BITFORCE_EITHER "N"
# define BITFORCE_EITHER_LEN 1
# define BITFORCE_NONCE "NONCE-FOUND"
# define BITFORCE_NONCE_LEN (sizeof(BITFORCE_NONCE)-1)
# define BITFORCE_NO_NONCE "NO-NONCE"
# define BITFORCE_NO_NONCE_MATCH 3
# define BITFORCE_IDLE "IDLE"
# define BITFORCE_IDLE_MATCH 1
# define BITFORCE_SLEEP_MS 500
# define BITFORCE_TIMEOUT_S 7
@ -62,62 +64,197 @@ enum {
@@ -62,62 +64,197 @@ enum {
# define KNAME_WORK "full work"
# define KNAME_RANGE "nonce range"
struct device_api bitforce_api ;
# define BITFORCE_BUFSIZ (0x200)
static void BFgets ( char * buf , size_t bufLen , int fd )
{
do {
buf [ 0 ] = ' \0 ' ;
- - bufLen ;
} while ( likely ( bufLen & & read ( fd , buf , 1 ) = = 1 & & ( buf + + ) [ 0 ] ! = ' \n ' ) ) ;
// If initialisation fails the first time,
// sleep this amount (ms) and try again
# define REINIT_TIME_FIRST_MS 100
// Max ms per sleep
# define REINIT_TIME_MAX_MS 800
// Keep trying up to this many us
# define REINIT_TIME_MAX 3000000
buf [ 0 ] = ' \0 ' ;
}
static const char * blank = " " ;
struct device_drv bitforce_drv ;
static ssize_t BFwrite ( int fd , const void * buf , ssize_t bufLen )
static void bitforce_initialise ( struct cgpu_info * bitforce , bool lock )
{
if ( ( bufLen ) ! = write ( fd , buf , bufLen ) )
return 0 ;
else
return bufLen ;
}
int err ;
# define BFclose(fd) close(fd)
if ( lock )
mutex_lock ( & bitforce - > device_mutex ) ;
static bool bitforce_detect_one ( const char * devpath )
// Reset
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_RESET ,
FTDI_VALUE_RESET , bitforce - > usbdev - > found - > interface , C_RESET ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: reset got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Set data control
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_DATA ,
FTDI_VALUE_DATA , bitforce - > usbdev - > found - > interface , C_SETDATA ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: setdata got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Set the baud
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_BAUD , FTDI_VALUE_BAUD ,
( FTDI_INDEX_BAUD & 0xff00 ) | bitforce - > usbdev - > found - > interface ,
C_SETBAUD ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: setbaud got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Set Flow Control
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_FLOW ,
FTDI_VALUE_FLOW , bitforce - > usbdev - > found - > interface , C_SETFLOW ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: setflowctrl got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Set Modem Control
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_MODEM ,
FTDI_VALUE_MODEM , bitforce - > usbdev - > found - > interface , C_SETMODEM ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: setmodemctrl got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Clear any sent data
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_RESET ,
FTDI_VALUE_PURGE_TX , bitforce - > usbdev - > found - > interface , C_PURGETX ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: purgetx got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
if ( bitforce - > usbinfo . nodev )
goto failed ;
// Clear any received data
err = usb_transfer ( bitforce , FTDI_TYPE_OUT , FTDI_REQUEST_RESET ,
FTDI_VALUE_PURGE_RX , bitforce - > usbdev - > found - > interface , C_PURGERX ) ;
if ( opt_debug )
applog ( LOG_DEBUG , " %s%i: purgerx got err %d " ,
bitforce - > drv - > name , bitforce - > device_id , err ) ;
failed :
if ( lock )
mutex_unlock ( & bitforce - > device_mutex ) ;
}
static bool bitforce_detect_one ( struct libusb_device * dev , struct usb_find_devices * found )
{
int fdDev = BFopen ( devpath ) ;
struct cgpu_info * bitforce ;
char pdevbuf [ 0x100 ] ;
char buf [ BITFORCE_BUFSIZ + 1 ] ;
char devpath [ 20 ] ;
int err , amount ;
char * s ;
struct timeval init_start , init_now ;
int init_sleep , init_count ;
bool ident_first ;
applog ( LOG_DEBUG , " BFL: Attempting to open %s " , devpath ) ;
struct cgpu_info * bitforce = NULL ;
bitforce = calloc ( 1 , sizeof ( * bitforce ) ) ;
bitforce - > drv = & bitforce_drv ;
bitforce - > deven = DEV_ENABLED ;
bitforce - > threads = 1 ;
if ( unlikely ( fdDev = = - 1 ) ) {
applog ( LOG_ERR , " BFL: Failed to open %s " , devpath ) ;
return false ;
if ( ! usb_init ( bitforce , dev , found ) ) {
applog ( LOG_ERR , " %s detect (%d:%d) failed to initialise (incorrect device?) " ,
bitforce - > drv - > dname ,
( int ) ( bitforce - > usbinfo . bus_number ) ,
( int ) ( bitforce - > usbinfo . device_address ) ) ;
goto shin ;
}
BFwrite ( fdDev , " ZGX " , 3 ) ;
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
if ( unlikely ( ! pdevbuf [ 0 ] ) ) {
applog ( LOG_ERR , " BFL: Error reading/timeout (ZGX) " ) ;
return 0 ;
sprintf ( devpath , " %d:%d " ,
( int ) ( bitforce - > usbinfo . bus_number ) ,
( int ) ( bitforce - > usbinfo . device_address ) ) ;
// Allow 2 complete attempts if the 1st time returns an unrecognised reply
ident_first = true ;
retry :
init_count = 0 ;
init_sleep = REINIT_TIME_FIRST_MS ;
gettimeofday ( & init_start , NULL ) ;
reinit :
bitforce_initialise ( bitforce , false ) ;
if ( ( err = usb_write ( bitforce , BITFORCE_IDENTIFY , BITFORCE_IDENTIFY_LEN , & amount , C_REQUESTIDENTIFY ) ) < 0 | | amount ! = BITFORCE_IDENTIFY_LEN ) {
applog ( LOG_ERR , " %s detect (%s) send identify request failed (%d:%d) " ,
bitforce - > drv - > dname , devpath , amount , err ) ;
goto unshin ;
}
BFclose ( fdDev ) ;
if ( unlikely ( ! strstr ( pdevbuf , " SHA256 " ) ) ) {
applog ( LOG_ERR , " BFL: Didn't recognise BitForce on %s " , devpath ) ;
return false ;
if ( ( err = usb_ftdi_read_nl ( bitforce , buf , sizeof ( buf ) - 1 , & amount , C_GETIDENTIFY ) ) < 0 | | amount < 1 ) {
init_count + + ;
gettimeofday ( & init_now , NULL ) ;
if ( us_tdiff ( & init_now , & init_start ) < = REINIT_TIME_MAX ) {
if ( init_count = = 2 ) {
applog ( LOG_WARNING , " %s detect (%s) 2nd init failed (%d:%d) - retrying " ,
bitforce - > drv - > dname , devpath , amount , err ) ;
}
nmsleep ( init_sleep ) ;
if ( ( init_sleep * 2 ) < = REINIT_TIME_MAX_MS )
init_sleep * = 2 ;
goto reinit ;
}
if ( init_count > 0 )
applog ( LOG_WARNING , " %s detect (%s) init failed %d times %.2fs " ,
bitforce - > drv - > dname , devpath , init_count , tdiff ( & init_now , & init_start ) ) ;
if ( err < 0 ) {
applog ( LOG_ERR , " %s detect (%s) error identify reply (%d:%d) " ,
bitforce - > drv - > dname , devpath , amount , err ) ;
} else {
applog ( LOG_ERR , " %s detect (%s) empty identify reply (%d) " ,
bitforce - > drv - > dname , devpath , amount ) ;
}
goto unshin ;
}
buf [ amount ] = ' \0 ' ;
if ( unlikely ( ! strstr ( buf , " SHA256 " ) ) ) {
if ( ident_first ) {
applog ( LOG_WARNING , " %s detect (%s) didn't recognise '%s' trying again ... " ,
bitforce - > drv - > dname , devpath , buf ) ;
ident_first = false ;
goto retry ;
}
applog ( LOG_ERR , " %s detect (%s) didn't recognise '%s' on 2nd attempt " ,
bitforce - > drv - > dname , devpath , buf ) ;
goto unshin ;
}
if ( likely ( ( ! memcmp ( buf , " >>>ID: " , 7 ) ) & & ( s = strstr ( buf + 3 , " >>> " ) ) ) ) {
s [ 0 ] = ' \0 ' ;
bitforce - > name = strdup ( buf + 7 ) ;
} else {
bitforce - > name = ( char * ) blank ;
}
// We have a real BitForce!
bitforce = calloc ( 1 , sizeof ( * bitforce ) ) ;
bitforce - > api = & bitforce_api ;
bitforce - > device_path = strdup ( devpath ) ;
bitforce - > deven = DEV_ENABLED ;
bitforce - > threads = 1 ;
applog ( LOG_DEBUG , " %s (%s) identified as: '%s' " ,
bitforce - > drv - > dname , devpath , bitforce - > name ) ;
/* Initially enable support for nonce range and disable it later if it
* fails */
if ( opt_bfl_noncerange ) {
@ -129,108 +266,39 @@ static bool bitforce_detect_one(const char *devpath)
@@ -129,108 +266,39 @@ static bool bitforce_detect_one(const char *devpath)
bitforce - > kname = KNAME_WORK ;
}
if ( likely ( ( ! memcmp ( pdevbuf , " >>>ID: " , 7 ) ) & & ( s = strstr ( pdevbuf + 3 , " >>> " ) ) ) ) {
s [ 0 ] = ' \0 ' ;
bitforce - > name = strdup ( pdevbuf + 7 ) ;
}
bitforce - > device_path = strdup ( devpath ) ;
if ( ! add_cgpu ( bitforce ) )
goto unshin ;
update_usb_stats ( bitforce ) ;
mutex_init ( & bitforce - > device_mutex ) ;
return add_cgpu ( bitforce ) ;
}
return true ;
# define LOAD_SYM(sym) do { \
if ( ! ( sym = dlsym ( dll , # sym ) ) ) { \
applog ( LOG_DEBUG , " Failed to load " # sym " , not using FTDI bitforce autodetect " ) ; \
goto out ; \
} \
} while ( 0 )
unshin :
# ifdef WIN32
static int bitforce_autodetect_ftdi ( void )
{
char devpath [ ] = " \\ \\ . \\ COMnnnnn " ;
char * devpathnum = & devpath [ 7 ] ;
char * * bufptrs ;
char * buf ;
int found = 0 ;
DWORD i ;
FT_STATUS ftStatus ;
DWORD numDevs ;
HMODULE dll = LoadLibrary ( " FTD2XX.DLL " ) ;
if ( ! dll ) {
applog ( LOG_DEBUG , " FTD2XX.DLL failed to load, not using FTDI bitforce autodetect " ) ;
return 0 ;
}
LOAD_SYM ( FT_ListDevices ) ;
LOAD_SYM ( FT_Open ) ;
LOAD_SYM ( FT_GetComPortNumber ) ;
LOAD_SYM ( FT_Close ) ;
ftStatus = FT_ListDevices ( & numDevs , NULL , FT_LIST_NUMBER_ONLY ) ;
if ( ftStatus ! = FT_OK ) {
applog ( LOG_DEBUG , " FTDI device count failed, not using FTDI bitforce autodetect " ) ;
goto out ;
}
applog ( LOG_DEBUG , " FTDI reports %u devices " , ( unsigned ) numDevs ) ;
buf = alloca ( 65 * numDevs ) ;
bufptrs = alloca ( sizeof ( * bufptrs ) * ( numDevs + 1 ) ) ;
for ( i = 0 ; i < numDevs ; + + i )
bufptrs [ i ] = & buf [ i * 65 ] ;
bufptrs [ numDevs ] = NULL ;
ftStatus = FT_ListDevices ( bufptrs , & numDevs , FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION ) ;
if ( ftStatus ! = FT_OK ) {
applog ( LOG_DEBUG , " FTDI device list failed, not using FTDI bitforce autodetect " ) ;
goto out ;
}
for ( i = numDevs ; i > 0 ; ) {
- - i ;
bufptrs [ i ] [ 64 ] = ' \0 ' ;
if ( ! ( strstr ( bufptrs [ i ] , " BitFORCE " ) & & strstr ( bufptrs [ i ] , " SHA256 " ) ) )
continue ;
FT_HANDLE ftHandle ;
if ( FT_OK ! = FT_Open ( i , & ftHandle ) )
continue ;
LONG lComPortNumber ;
ftStatus = FT_GetComPortNumber ( ftHandle , & lComPortNumber ) ;
FT_Close ( ftHandle ) ;
if ( FT_OK ! = ftStatus | | lComPortNumber < 0 )
continue ;
sprintf ( devpathnum , " %d " , ( int ) lComPortNumber ) ;
if ( bitforce_detect_one ( devpath ) )
+ + found ;
}
usb_uninit ( bitforce ) ;
out :
dlclose ( dll ) ;
return found ;
}
# else
static int bitforce_autodetect_ftdi ( void )
{
return 0 ;
}
# endif
shin :
static int bitforce_detect_auto ( void )
{
return ( serial_autodetect_udev ( bitforce_detect_one , " BitFORCE*SHA256 " ) ? :
serial_autodetect_devserial ( bitforce_detect_one , " BitFORCE_SHA256 " ) ? :
bitforce_autodetect_ftdi ( ) ? :
0 ) ;
free ( bitforce - > device_path ) ;
if ( bitforce - > name ! = blank )
free ( bitforce - > name ) ;
if ( bitforce - > drv - > copy )
free ( bitforce - > drv ) ;
free ( bitforce ) ;
return false ;
}
static void bitforce_detect ( void )
{
serial_detect_auto ( & bitforce_api , bitforce_detect_one , bitforce_detect_auto ) ;
usb_detect ( & bitforce_drv , bitforce_detect_one ) ;
}
static void get_bitforce_statline_before ( char * buf , struct cgpu_info * bitforce )
@ -247,105 +315,17 @@ static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce)
@@ -247,105 +315,17 @@ static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce)
static bool bitforce_thread_prepare ( struct thr_info * thr )
{
struct cgpu_info * bitforce = thr - > cgpu ;
int fdDev = BFopen ( bitforce - > device_path ) ;
struct timeval now ;
if ( unlikely ( fdDev = = - 1 ) ) {
applog ( LOG_ERR , " BFL%i: Failed to open %s " , bitforce - > device_id , bitforce - > device_path ) ;
return false ;
}
bitforce - > device_fd = fdDev ;
applog ( LOG_INFO , " BFL%i: Opened %s " , bitforce - > device_id , bitforce - > device_path ) ;
gettimeofday ( & now , NULL ) ;
get_datestamp ( bitforce - > init , & now ) ;
return true ;
}
static void bitforce_clear_buffer ( struct cgpu_info * bitforce )
{
int fdDev = bitforce - > device_fd ;
char pdevbuf [ 0x100 ] ;
int count = 0 ;
if ( ! fdDev )
return ;
applog ( LOG_DEBUG , " BFL%i: Clearing read buffer " , bitforce - > device_id ) ;
mutex_lock ( & bitforce - > device_mutex ) ;
do {
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
} while ( pdevbuf [ 0 ] & & ( + + count < 10 ) ) ;
mutex_unlock ( & bitforce - > device_mutex ) ;
}
void bitforce_init ( struct cgpu_info * bitforce )
{
char * devpath = bitforce - > device_path ;
int fdDev = bitforce - > device_fd , retries = 0 ;
char pdevbuf [ 0x100 ] ;
char * s ;
applog ( LOG_WARNING , " BFL%i: Re-initialising " , bitforce - > device_id ) ;
bitforce_clear_buffer ( bitforce ) ;
mutex_lock ( & bitforce - > device_mutex ) ;
if ( fdDev ) {
BFclose ( fdDev ) ;
sleep ( 5 ) ;
}
bitforce - > device_fd = 0 ;
fdDev = BFopen ( devpath ) ;
if ( unlikely ( fdDev = = - 1 ) ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " BFL%i: Failed to open %s " , bitforce - > device_id , devpath ) ;
return ;
}
do {
BFwrite ( fdDev , " ZGX " , 3 ) ;
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
if ( unlikely ( ! pdevbuf [ 0 ] ) ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " BFL%i: Error reading/timeout (ZGX) " , bitforce - > device_id ) ;
return ;
}
if ( retries + + )
nmsleep ( 10 ) ;
} while ( ! strstr ( pdevbuf , " BUSY " ) & & ( retries * 10 < BITFORCE_TIMEOUT_MS ) ) ;
if ( unlikely ( ! strstr ( pdevbuf , " SHA256 " ) ) ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " BFL%i: Didn't recognise BitForce on %s returned: %s " , bitforce - > device_id , devpath , pdevbuf ) ;
return ;
}
if ( likely ( ( ! memcmp ( pdevbuf , " >>>ID: " , 7 ) ) & & ( s = strstr ( pdevbuf + 3 , " >>> " ) ) ) ) {
s [ 0 ] = ' \0 ' ;
bitforce - > name = strdup ( pdevbuf + 7 ) ;
}
bitforce - > device_fd = fdDev ;
bitforce - > sleep_ms = BITFORCE_SLEEP_MS ;
mutex_unlock ( & bitforce - > device_mutex ) ;
}
static void bitforce_flash_led ( struct cgpu_info * bitforce )
{
int fdDev = bitforce - > device_fd ;
if ( ! fdDev )
return ;
int err , amount ;
/* Do not try to flash the led if we're polling for a result to
* minimise the chance of interleaved results */
@ -353,19 +333,22 @@ static void bitforce_flash_led(struct cgpu_info *bitforce)
@@ -353,19 +333,22 @@ static void bitforce_flash_led(struct cgpu_info *bitforce)
return ;
/* It is not critical flashing the led so don't get stuck if we
* can ' t grab the mutex here */
* can ' t grab the mutex now */
if ( mutex_trylock ( & bitforce - > device_mutex ) )
return ;
BFwrite ( fdDev , " ZMX " , 3 ) ;
if ( ( err = usb_write ( bitforce , BITFORCE_FLASH , BITFORCE_FLASH_LEN , & amount , C_REQUESTFLASH ) ) < 0 | | amount ! = BITFORCE_FLASH_LEN ) {
applog ( LOG_ERR , " %s%i: flash request failed (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
} else {
/* However, this stops anything else getting a reply
* So best to delay any other access to the BFL */
sleep ( 4 ) ;
}
/* Once we've tried - don't do it until told to again */
bitforce - > flash_led = false ;
/* However, this stops anything else getting a reply
* So best to delay any other access to the BFL */
sleep ( 4 ) ;
mutex_unlock ( & bitforce - > device_mutex ) ;
return ; // nothing is returned by the BFL
@ -373,11 +356,12 @@ static void bitforce_flash_led(struct cgpu_info *bitforce)
@@ -373,11 +356,12 @@ static void bitforce_flash_led(struct cgpu_info *bitforce)
static bool bitforce_get_temp ( struct cgpu_info * bitforce )
{
int fdDev = bitforce - > device_fd ;
char pdevbuf [ 0x100 ] ;
char buf [ BITFORCE_BUFSIZ + 1 ] ;
int err , amount ;
char * s ;
if ( ! fdDev )
// Device is gone
if ( bitforce - > usbinfo . nodev )
return false ;
/* Do not try to get the temperature if we're polling for a result to
@ -396,18 +380,30 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
@@ -396,18 +380,30 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
if ( mutex_trylock ( & bitforce - > device_mutex ) )
return false ;
BFwrite ( fdDev , " ZLX " , 3 ) ;
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
mutex_unlock ( & bitforce - > device_mutex ) ;
if ( unlikely ( ! pdevbuf [ 0 ] ) ) {
applog ( LOG_ERR , " BFL%i: Error: Get temp returned empty string/timed out " , bitforce - > device_id ) ;
if ( ( err = usb_write ( bitforce , BITFORCE_TEMPERATURE , BITFORCE_TEMPERATURE_LEN , & amount , C_REQUESTTEMPERATURE ) ) < 0 | | amount ! = BITFORCE_TEMPERATURE_LEN ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " %s%i: Error: Request temp invalid/timed out (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
bitforce - > hw_errors + + ;
return false ;
}
if ( ( ! strncasecmp ( pdevbuf , " TEMP " , 4 ) ) & & ( s = strchr ( pdevbuf + 4 , ' : ' ) ) ) {
if ( ( err = usb_ftdi_read_nl ( bitforce , buf , sizeof ( buf ) - 1 , & amount , C_GETTEMPERATURE ) ) < 0 | | amount < 1 ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
if ( err < 0 ) {
applog ( LOG_ERR , " %s%i: Error: Get temp return invalid/timed out (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
} else {
applog ( LOG_ERR , " %s%i: Error: Get temp returned nothing (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
}
bitforce - > hw_errors + + ;
return false ;
}
mutex_unlock ( & bitforce - > device_mutex ) ;
if ( ( ! strncasecmp ( buf , " TEMP " , 4 ) ) & & ( s = strchr ( buf + 4 , ' : ' ) ) ) {
float temp = strtof ( s + 1 , NULL ) ;
/* Cope with older software that breaks and reads nonsense
@ -418,7 +414,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
@@ -418,7 +414,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
if ( temp > 0 ) {
bitforce - > temp = temp ;
if ( unlikely ( bitforce - > cutofftemp > 0 & & temp > bitforce - > cutofftemp ) ) {
applog ( LOG_WARNING , " BFL%i: Hit thermal cutoff limit, disabling! " , bitforce - > device_id ) ;
applog ( LOG_WARNING , " %s%i: Hit thermal cutoff limit, disabling! " ,
bitforce - > drv - > name , bitforce - > device_id ) ;
bitforce - > deven = DEV_RECOVER ;
dev_error ( bitforce , REASON_DEV_THERMAL_CUTOFF ) ;
}
@ -427,11 +424,12 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
@@ -427,11 +424,12 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
/* Use the temperature monitor as a kind of watchdog for when
* our responses are out of sync and flush the buffer to
* hopefully recover */
applog ( LOG_WARNING , " BFL%i: Garbled response probably throttling, clearing buffer " , bitforce - > device_id ) ;
applog ( LOG_WARNING , " %s%i: Garbled response probably throttling, clearing buffer " ,
bitforce - > drv - > name , bitforce - > device_id ) ;
dev_error ( bitforce , REASON_DEV_THROTTLE ) ;
/* Count throttling episodes as hardware errors */
bitforce - > hw_errors + + ;
bitforce_clear_buffer ( bitforce ) ;
bitforce_initialise ( bitforce , tru e ) ;
return false ;
}
@ -441,35 +439,53 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
@@ -441,35 +439,53 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
static bool bitforce_send_work ( struct thr_info * thr , struct work * work )
{
struct cgpu_info * bitforce = thr - > cgpu ;
int fdDev = bitforce - > device_fd ;
unsigned char ob [ 70 ] ;
char pdevbuf [ 0x100 ] ;
char buf [ BITFORCE_BUFSIZ + 1 ] ;
int err , amount ;
char * s ;
char * cmd ;
int len ;
if ( ! fdDev )
return false ;
re_send :
if ( bitforce - > nonce_range ) {
cmd = BITFORCE_SENDRANGE ;
len = BITFORCE_SENDRANGE_LEN ;
} else {
cmd = BITFORCE_SENDWORK ;
len = BITFORCE_SENDWORK_LEN ;
}
mutex_lock ( & bitforce - > device_mutex ) ;
if ( bitforce - > nonce_range )
BFwrite ( fdDev , " ZPX " , 3 ) ;
else
BFwrite ( fdDev , " ZDX " , 3 ) ;
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
if ( ! pdevbuf [ 0 ] | | ! strncasecmp ( pdevbuf , " B " , 1 ) ) {
if ( ( err = usb_write ( bitforce , cmd , len , & amount , C_REQUESTSENDWORK ) ) < 0 | | amount ! = len ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " %s%i: request send work failed (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
return false ;
}
if ( ( err = usb_ftdi_read_nl ( bitforce , buf , sizeof ( buf ) - 1 , & amount , C_REQUESTSENDWORKSTATUS ) ) < 0 ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " %s%d: read request send work status failed (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
return false ;
}
if ( amount = = 0 | | ! buf [ 0 ] | | ! strncasecmp ( buf , " B " , 1 ) ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
nmsleep ( WORK_CHECK_INTERVAL_MS ) ;
goto re_send ;
} else if ( unlikely ( strncasecmp ( pdevbuf , " OK " , 2 ) ) ) {
} else if ( unlikely ( strncasecmp ( buf , " OK " , 2 ) ) ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
if ( bitforce - > nonce_range ) {
applog ( LOG_WARNING , " BFL%i: Does not support nonce range, disabling " , bitforce - > device_id ) ;
applog ( LOG_WARNING , " %s%i: Does not support nonce range, disabling " ,
bitforce - > drv - > name , bitforce - > device_id ) ;
bitforce - > nonce_range = false ;
bitforce - > sleep_ms * = 5 ;
bitforce - > kname = KNAME_WORK ;
goto re_send ;
}
applog ( LOG_ERR , " BFL%i: Error: Send work reports: %s " , bitforce - > device_id , pdevbuf ) ;
applog ( LOG_ERR , " %s%i: Error: Send work reports: %s " ,
bitforce - > drv - > name , bitforce - > device_id , buf ) ;
return false ;
}
@ -479,7 +495,7 @@ re_send:
@@ -479,7 +495,7 @@ re_send:
if ( ! bitforce - > nonce_range ) {
sprintf ( ( char * ) ob + 8 + 32 + 12 , " >>>>>>>> " ) ;
work - > blk . nonce = bitforce - > nonces = 0xffffffff ;
BFwrite ( fdDev , ob , 60 ) ;
len = 60 ;
} else {
uint32_t * nonce ;
@ -491,26 +507,41 @@ re_send:
@@ -491,26 +507,41 @@ re_send:
* nonce = htobe32 ( work - > blk . nonce + bitforce - > nonces ) ;
work - > blk . nonce + = bitforce - > nonces + 1 ;
sprintf ( ( char * ) ob + 8 + 32 + 12 + 8 , " >>>>>>>> " ) ;
BFwrite ( fdDev , ob , 68 ) ;
len = 68 ;
}
if ( ( err = usb_write ( bitforce , ( char * ) ob , len , & amount , C_SENDWORK ) ) < 0 | | amount ! = len ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " %s%i: send work failed (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
return false ;
}
if ( ( err = usb_ftdi_read_nl ( bitforce , buf , sizeof ( buf ) - 1 , & amount , C_SENDWORKSTATUS ) ) < 0 ) {
mutex_unlock ( & bitforce - > device_mutex ) ;
applog ( LOG_ERR , " %s%d: read send work status failed (%d:%d) " ,
bitforce - > drv - > name , bitforce - > device_id , amount , err ) ;
return false ;
}
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
mutex_unlock ( & bitforce - > device_mutex ) ;
if ( opt_debug ) {
s = bin2hex ( ob + 8 , 44 ) ;
applog ( LOG_DEBUG , " BFL%i: block data: %s " , bitforce - > device_id , s ) ;
applog ( LOG_DEBUG , " %s%i: block data: %s " ,
bitforce - > drv - > name , bitforce - > device_id , s ) ;
free ( s ) ;
}
if ( unlikely ( ! pdevbuf [ 0 ] ) ) {
applog ( LOG_ERR , " BFL%i: Error: Send block data returned empty string/timed out " , bitforce - > device_id ) ;
if ( amount = = 0 | | ! buf [ 0 ] ) {
applog ( LOG_ERR , " %s%i: Error: Send block data returned empty string/timed out " ,
bitforce - > drv - > name , bitforce - > device_id ) ;
return false ;
}
if ( unlikely ( strncasecmp ( pdevbuf , " OK " , 2 ) ) ) {
applog ( LOG_ERR , " BFL%i: Error: Send block data reports: %s " , bitforce - > device_id , pdevbuf ) ;
if ( unlikely ( strncasecmp ( buf , " OK " , 2 ) ) ) {
applog ( LOG_ERR , " %s%i: Error: Send block data reports: %s " ,
bitforce - > drv - > name , bitforce - > device_id , buf ) ;
return false ;
}
@ -521,53 +552,52 @@ re_send:
@@ -521,53 +552,52 @@ re_send:
static int64_t bitforce_get_result ( struct thr_info * thr , struct work * work )
{
struct cgpu_info * bitforce = thr - > cgpu ;
int fdDev = bitforce - > device_fd ;
unsigned int delay_time_ms ;
struct timeval elapsed ;
struct timeval now ;
char pdevbuf [ 0x100 ] ;
char buf [ BITFORCE_BUFSIZ + 1 ] ;
int amount ;
char * pnoncebuf ;
uint32_t nonce ;
if ( ! fdDev )
return - 1 ;
while ( 1 ) {
if ( unlikely ( thr - > work_restart ) )
return 0 ;
mutex_lock ( & bitforce - > device_mutex ) ;
BFwrite ( fdDev , " ZFX " , 3 ) ;
pdevbuf [ 0 ] = ' \0 ' ;
BFgets ( pdevbuf , sizeof ( pdevbuf ) , fdDev ) ;
usb_write ( bitforce , BITFORCE_WORKSTATUS , BITFORCE_WORKSTATUS_LEN , & amount , C_REQUESTWORKSTATUS ) ;
usb_ftdi_read_nl ( bitforce , buf , sizeof ( buf ) - 1 , & amount , C_GETWORKSTATUS ) ;
mutex_unlock ( & bitforce - > device_mutex ) ;
gettimeofday ( & now , NULL ) ;
timersub ( & now , & bitforce - > work_start_tv , & elapsed ) ;
if ( elapsed . tv_sec > = BITFORCE_LONG_TIMEOUT_S ) {
applog ( LOG_ERR , " BFL%i: took %dms - longer than %dms " , bitforce - > device_id ,
applog ( LOG_ERR , " %s%i: took %dms - longer than %dms " ,
bitforce - > drv - > name , bitforce - > device_id ,
tv_to_ms ( elapsed ) , BITFORCE_LONG_TIMEOUT_MS ) ;
return 0 ;
}
if ( pdev buf[ 0 ] & & strncasecmp ( pdev buf, " B " , 1 ) ) /* BFL does not respond during throttling */
if ( amount > 0 & & buf [ 0 ] & & strncasecmp ( buf , " B " , 1 ) ) /* BFL does not respond during throttling */
break ;
/* if BFL is throttling, no point checking so quickly */
delay_time_ms = ( pdev buf[ 0 ] ? BITFORCE_CHECK_INTERVAL_MS : 2 * WORK_CHECK_INTERVAL_MS ) ;
delay_time_ms = ( buf [ 0 ] ? BITFORCE_CHECK_INTERVAL_MS : 2 * WORK_CHECK_INTERVAL_MS ) ;
nmsleep ( delay_time_ms ) ;
bitforce - > wait_ms + = delay_time_ms ;
}
if ( elapsed . tv_sec > BITFORCE_TIMEOUT_S ) {
applog ( LOG_ERR , " BFL%i: took %dms - longer than %dms " , bitforce - > device_id ,
applog ( LOG_ERR , " %s%i: took %dms - longer than %dms " ,
bitforce - > drv - > name , bitforce - > device_id ,
tv_to_ms ( elapsed ) , BITFORCE_TIMEOUT_MS ) ;
dev_error ( bitforce , REASON_DEV_OVER_HEAT ) ;
if ( ! pdevbuf [ 0 ] ) /* Only return if we got nothing after timeout - there still may be results */
/* Only return if we got nothing after timeout - there still may be results */
if ( amount = = 0 )
return 0 ;
} else if ( ! strncasecmp ( pdevbuf , " N " , 1 ) ) { /* Hashing complete (NONCE-FOUND or NO-NONCE) */
} else if ( ! strncasecmp ( buf , BITFORCE_EITHER , BITFORCE_EITHER_LEN ) ) {
/* Simple timing adjustment. Allow a few polls to cope with
* OS timer delays being variably reliable . wait_ms will
* always equal sleep_ms when we ' ve waited greater than or
@ -584,26 +614,31 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
@@ -584,26 +614,31 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
}
if ( delay_time_ms ! = bitforce - > sleep_ms )
applog ( LOG_DEBUG , " BFL%i: Wait time changed to: %d, waited %u " , bitforce - > device_id , bitforce - > sleep_ms , bitforce - > wait_ms ) ;
applog ( LOG_DEBUG , " %s%i: Wait time changed to: %d, waited %u " ,
bitforce - > drv - > name , bitforce - > device_id ,
bitforce - > sleep_ms , bitforce - > wait_ms ) ;
/* Work out the average time taken. Float for calculation, uint for display */
bitforce - > avg_wait_f + = ( tv_to_ms ( elapsed ) - bitforce - > avg_wait_f ) / TIME_AVG_CONSTANT ;
bitforce - > avg_wait_d = ( unsigned int ) ( bitforce - > avg_wait_f + 0.5 ) ;
}
applog ( LOG_DEBUG , " BFL%i: waited %dms until %s " , bitforce - > device_id , bitforce - > wait_ms , pdevbuf ) ;
if ( ! strncasecmp ( & pdevbuf [ 2 ] , " - " , 1 ) )
applog ( LOG_DEBUG , " %s%i: waited %dms until %s " ,
bitforce - > drv - > name , bitforce - > device_id ,
bitforce - > wait_ms , buf ) ;
if ( ! strncasecmp ( buf , BITFORCE_NO_NONCE , BITFORCE_NO_NONCE_MATCH ) )
return bitforce - > nonces ; /* No valid nonce found */
else if ( ! strncasecmp ( pdevbuf , " I " , 1 ) )
else if ( ! strncasecmp ( buf , BITFORCE_IDLE , BITFORCE_IDLE_MATCH ) )
return 0 ; /* Device idle */
else if ( strncasecmp ( pdevbuf , " NONCE-FOUND " , 11 ) ) {
else if ( strncasecmp ( buf , BITFORCE_NONCE , BITFORCE_NONCE_LEN ) ) {
bitforce - > hw_errors + + ;
applog ( LOG_WARNING , " BFL%i: Error: Get result reports: %s " , bitforce - > device_id , pdevbuf ) ;
bitforce_clear_buffer ( bitforce ) ;
applog ( LOG_WARNING , " %s%i: Error: Get result reports: %s " ,
bitforce - > drv - > name , bitforce - > device_id , buf ) ;
bitforce_initialise ( bitforce , true ) ;
return 0 ;
}
pnoncebuf = & pdev buf[ 12 ] ;
pnoncebuf = & buf [ 12 ] ;
while ( 1 ) {
hex2bin ( ( void * ) & nonce , pnoncebuf , 4 ) ;
@ -612,7 +647,8 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
@@ -612,7 +647,8 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
# endif
if ( unlikely ( bitforce - > nonce_range & & ( nonce > = work - > blk . nonce | |
( work - > blk . nonce > 0 & & nonce < work - > blk . nonce - bitforce - > nonces - 1 ) ) ) ) {
applog ( LOG_WARNING , " BFL%i: Disabling broken nonce range support " , bitforce - > device_id ) ;
applog ( LOG_WARNING , " %s%i: Disabling broken nonce range support " ,
bitforce - > drv - > name , bitforce - > device_id ) ;
bitforce - > nonce_range = false ;
work - > blk . nonce = 0xffffffff ;
bitforce - > sleep_ms * = 5 ;
@ -628,19 +664,16 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
@@ -628,19 +664,16 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
return bitforce - > nonces ;
}
static void bitforce_shutdown ( struct thr_info * thr )
static void bitforce_shutdown ( __maybe_unused struct thr_info * thr )
{
struct cgpu_info * bitforce = thr - > cgpu ;
BFclose ( bitforce - > device_fd ) ;
bitforce - > device_fd = 0 ;
// struct cgpu_info *bitforce = thr->cgpu;
}
static void biforce_thread_enable ( struct thr_info * thr )
{
struct cgpu_info * bitforce = thr - > cgpu ;
bitforce_init ( bitforce ) ;
bitforce_initialise ( bitforce , tru e ) ;
}
static int64_t bitforce_scanhash ( struct thr_info * thr , struct work * work , int64_t __maybe_unused max_nonce )
@ -649,6 +682,10 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
@@ -649,6 +682,10 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
bool send_ret ;
int64_t ret ;
// Device is gone
if ( bitforce - > usbinfo . nodev )
return - 1 ;
send_ret = bitforce_send_work ( thr , work ) ;
if ( ! restart_wait ( bitforce - > sleep_ms ) )
@ -665,11 +702,11 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
@@ -665,11 +702,11 @@ static int64_t bitforce_scanhash(struct thr_info *thr, struct work *work, int64_
if ( ret = = - 1 ) {
ret = 0 ;
applog ( LOG_ERR , " BFL%i: Comms error " , bitforce - > device_id ) ;
applog ( LOG_ERR , " %s%i: Comms error " , bitforce - > drv - > name , bitforce - > device_id ) ;
dev_error ( bitforce , REASON_DEV_COMMS_ERROR ) ;
bitforce - > hw_errors + + ;
/* empty read buffer */
bitforce_clear_buffer ( bitforce ) ;
bitforce_initialise ( bitforce , tru e ) ;
}
return ret ;
}
@ -692,7 +729,8 @@ static bool bitforce_thread_init(struct thr_info *thr)
@@ -692,7 +729,8 @@ static bool bitforce_thread_init(struct thr_info *thr)
/* Pause each new thread at least 100ms between initialising
* so the devices aren ' t making calls all at the same time . */
wait = thr - > id * MAX_START_DELAY_MS ;
applog ( LOG_DEBUG , " BFL%i: Delaying start by %dms " , bitforce - > device_id , wait / 1000 ) ;
applog ( LOG_DEBUG , " %s%d: Delaying start by %dms " ,
bitforce - > drv - > name , bitforce - > device_id , wait / 1000 ) ;
nmsleep ( wait ) ;
return true ;
@ -712,12 +750,12 @@ static struct api_data *bitforce_api_stats(struct cgpu_info *cgpu)
@@ -712,12 +750,12 @@ static struct api_data *bitforce_api_stats(struct cgpu_info *cgpu)
return root ;
}
struct device_api bitforce_api = {
. dname = " bitforce " ,
struct device_drv bitforce_drv = {
. drv = DRIVER_BITFORCE ,
. dname = " BitForce " ,
. name = " BFL " ,
. api _detect = bitforce_detect ,
. drv _detect = bitforce_detect ,
. get_api_stats = bitforce_api_stats ,
. reinit_device = bitforce_init ,
. get_statline_before = get_bitforce_statline_before ,
. get_stats = bitforce_get_stats ,
. identify_device = bitforce_identify ,