@ -2,6 +2,8 @@
* libztex . c - Ztex 1.15 x fpga board support library
* libztex . c - Ztex 1.15 x fpga board support library
*
*
* Copyright ( c ) 2012 nelisky . btc @ gmail . com
* Copyright ( c ) 2012 nelisky . btc @ gmail . com
* Copyright ( c ) 2012 Denis Ahrens < denis @ h3q . com >
* Copyright ( c ) 2012 Peter Stuge < peter @ stuge . se >
*
*
* This work is based upon the Java SDK provided by ztex which is
* This work is based upon the Java SDK provided by ztex which is
* Copyright ( C ) 2009 - 2011 ZTEX GmbH .
* Copyright ( C ) 2009 - 2011 ZTEX GmbH .
@ -47,21 +49,147 @@
# define CAPABILITY_MULTI_FPGA 0,7
# define CAPABILITY_MULTI_FPGA 0,7
static bool libztex_checkDevice ( struct libusb_device * dev )
enum check_result {
CHECK_ERROR ,
CHECK_IS_NOT_ZTEX ,
CHECK_OK ,
CHECK_RESCAN ,
} ;
static enum check_result libztex_checkDevice ( struct libusb_device * dev )
{
{
FILE * fp = NULL ;
libusb_device_handle * hndl = NULL ;
struct libusb_device_descriptor desc ;
struct libusb_device_descriptor desc ;
int err ;
int i , ret = CHECK_ERROR , err , cnt ;
size_t got_bytes , length ;
unsigned char buf [ 64 ] , * fw_buf ;
char * firmware = " ztex_ufm1_15y1.bin " ;
err = libusb_get_device_descriptor ( dev , & desc ) ;
err = libusb_get_device_descriptor ( dev , & desc ) ;
if ( unlikely ( err ! = 0 ) ) {
if ( unlikely ( err ! = 0 ) ) {
applog ( LOG_ERR , " Ztex check device: Failed to open read descriptor with error %d " , err ) ;
applog ( LOG_ERR , " Ztex check device: Failed to open read descriptor with error %d " , err ) ;
return false ;
return CHECK_ERROR ;
}
}
if ( ! ( desc . idVendor = = LIBZTEX_IDVENDOR & & desc . idProduct = = LIBZTEX_IDPRODUCT ) ) {
if ( desc . idVendor ! = LIBZTEX_IDVENDOR | | desc . idProduct ! = LIBZTEX_IDPRODUCT ) {
applog ( LOG_DEBUG , " Not a ZTEX device %0.4x:%0.4x " , desc . idVendor , desc . idProduct ) ;
applog ( LOG_DEBUG , " Not a ZTEX device %0.4x:%0.4x " , desc . idVendor , desc . idProduct ) ;
return false ;
return CHECK_IS_NOT_ZTEX ;
}
}
return true ;
err = libusb_open ( dev , & hndl ) ;
if ( err ! = LIBUSB_SUCCESS ) {
applog ( LOG_ERR , " %s: Can not open ZTEX device: %s " , __func__ , libusb_error_name ( err ) ) ;
goto done ;
}
cnt = libusb_control_transfer ( hndl , 0xc0 , 0x22 , 0 , 0 , buf , 40 , 500 ) ;
if ( unlikely ( cnt < 0 ) ) {
applog ( LOG_ERR , " Ztex check device: Failed to read ztex descriptor with err %d " , cnt ) ;
goto done ;
}
if ( buf [ 0 ] ! = 40 | | buf [ 1 ] ! = 1 | | buf [ 2 ] ! = ' Z ' | | buf [ 3 ] ! = ' T ' | | buf [ 4 ] ! = ' E ' | | buf [ 5 ] ! = ' X ' ) {
applog ( LOG_ERR , " Ztex check device: Error reading ztex descriptor " ) ;
goto done ;
}
if ( buf [ 6 ] ! = 10 )
{
ret = CHECK_IS_NOT_ZTEX ;
goto done ;
}
// 15 = 1.15y 13 = 1.15d or 1.15x
switch ( buf [ 7 ] )
{
case 13 :
applog ( LOG_ERR , " Found ztex board 1.15d or 1.15x but currently unsupported! " ) ;
ret = CHECK_IS_NOT_ZTEX ;
goto done ;
case 15 :
applog ( LOG_ERR , " Found ztex board 1.15y " ) ;
break ;
default :
applog ( LOG_ERR , " Found unknown ztex board " ) ;
ret = CHECK_IS_NOT_ZTEX ;
goto done ;
}
// testing for dummy firmware
if ( buf [ 8 ] ! = 0 ) {
ret = CHECK_OK ;
goto done ;
}
applog ( LOG_ERR , " Found dummy firmware, trying to send mining firmware: %s " , firmware ) ;
// reset 1
buf [ 0 ] = 1 ;
cnt = libusb_control_transfer ( hndl , 0x40 , 0xA0 , 0xE600 , 0 , buf , 1 , 1000 ) ;
if ( cnt < 0 )
{
applog ( LOG_ERR , " Ztex reset 1 failed: %s " , libusb_error_name ( cnt ) ) ;
goto done ;
}
fp = open_bitstream ( " ztex " , firmware ) ;
if ( ! fp ) {
applog ( LOG_ERR , " failed to open firmware file '%s' " , firmware ) ;
goto done ;
}
if ( 0 ! = fseek ( fp , 0 , SEEK_END ) ) {
applog ( LOG_ERR , " Ztex firmware fseek: %s " , strerror ( errno ) ) ;
goto done ;
}
length = ftell ( fp ) ;
rewind ( fp ) ;
fw_buf = malloc ( length ) ;
if ( ! fw_buf ) {
applog ( LOG_ERR , " %s: Can not allocate memory: %s " , __func__ , strerror ( errno ) ) ;
goto done ;
}
got_bytes = fread ( fw_buf , 1 , length , fp ) ;
fclose ( fp ) ;
fp = NULL ;
if ( got_bytes < length ) {
applog ( LOG_ERR , " %s: Incomplete firmware read: %d/%d " , __func__ , got_bytes , length ) ;
goto done ;
}
for ( i = 0 ; i < length ; i + = 256 ) {
// firmware wants data in small chunks like 256 bytes
int numbytes = ( length - i ) < 256 ? ( length - i ) : 256 ;
int k = libusb_control_transfer ( hndl , 0x40 , 0xA0 , i , 0 , fw_buf + i , numbytes , 1000 ) ;
if ( k < numbytes )
{
applog ( LOG_ERR , " Ztex device: Failed to write firmware at %d with: %s " , i , libusb_error_name ( k ) ) ;
goto done ;
}
}
// reset 0
buf [ 0 ] = 0 ;
err = libusb_control_transfer ( hndl , 0x40 , 0xA0 , 0xE600 , 0 , buf , 1 , 1000 ) ;
if ( err < 0 )
{
applog ( LOG_ERR , " Ztex reset 0 failed: %s " , libusb_error_name ( err ) ) ;
goto done ;
}
applog ( LOG_ERR , " Ztex device: succesfully wrote firmware " ) ;
ret = CHECK_RESCAN ;
done :
if ( fp )
fclose ( fp ) ;
if ( hndl )
libusb_close ( hndl ) ;
return ret ;
}
}
static bool libztex_checkCapability ( struct libztex_device * ztex , int i , int j )
static bool libztex_checkCapability ( struct libztex_device * ztex , int i , int j )
@ -408,35 +536,21 @@ int libztex_suspend(struct libztex_device *ztex) {
}
}
int libztex_prepare_device ( struct libusb_device * dev , struct libztex_device * * ztex ) {
int libztex_prepare_device ( struct libusb_device * dev , struct libztex_device * * ztex ) {
struct libztex_device * newdev ;
struct libztex_device * newdev = * ztex ;
int i , cnt , err ;
int i , cnt , err ;
unsigned char buf [ 64 ] ;
unsigned char buf [ 64 ] ;
uint16_t langid ;
uint16_t langid ;
newdev = malloc ( sizeof ( struct libztex_device ) ) ;
err = libusb_open ( dev , & newdev - > hndl ) ;
newdev - > bitFileName = NULL ;
if ( err ! = LIBUSB_SUCCESS ) {
newdev - > numberOfFpgas = - 1 ;
applog ( LOG_ERR , " %s: Can not open ZTEX device: %s " , __func__ , libusb_error_name ( err ) ) ;
newdev - > valid = false ;
return CHECK_ERROR ;
newdev - > hndl = NULL ;
}
* ztex = newdev ;
err = libusb_get_device_descriptor ( dev , & newdev - > descriptor ) ;
err = libusb_get_device_descriptor ( dev , & newdev - > descriptor ) ;
if ( unlikely ( err ! = 0 ) ) {
if ( unlikely ( err ! = 0 ) ) {
applog ( LOG_ERR , " Ztex check device: Failed to open read descriptor with error %d " , err ) ;
applog ( LOG_ERR , " Ztex check device: Failed to open read descriptor with error %d " , err ) ;
return err ;
return CHECK_ERROR ;
}
// Check vendorId and productId
if ( ! ( newdev - > descriptor . idVendor = = LIBZTEX_IDVENDOR & &
newdev - > descriptor . idProduct = = LIBZTEX_IDPRODUCT ) ) {
applog ( LOG_ERR , " Not a ztex device? %0.4X, %0.4X " , newdev - > descriptor . idVendor , newdev - > descriptor . idProduct ) ;
return 1 ;
}
err = libusb_open ( dev , & newdev - > hndl ) ;
if ( unlikely ( err ! = 0 ) ) {
applog ( LOG_ERR , " Ztex check device: Failed to open handle with error %d " , err ) ;
return err ;
}
}
/* We open code string descriptor retrieval and ASCII decoding here
/* We open code string descriptor retrieval and ASCII decoding here
@ -587,52 +701,104 @@ void libztex_destroy_device(struct libztex_device* ztex)
int libztex_scanDevices ( struct libztex_dev_list * * * devs_p )
int libztex_scanDevices ( struct libztex_dev_list * * * devs_p )
{
{
int usbdevices [ LIBZTEX_MAX_DESCRIPTORS ] ;
int usbdevices [ LIBZTEX_MAX_DESCRIPTORS ] ;
struct libztex_dev_list * * devs ;
struct libztex_dev_list * * devs = NULL ;
struct libztex_device * ztex ;
struct libusb_device_descriptor dev_descr ;
int found = 0 , pos = 0 , err ;
struct libztex_device * ztex = NULL ;
libusb_device * * list ;
int found , max_found = 0 , pos = 0 , err , rescan , ret = 0 ;
ssize_t cnt , i = 0 ;
libusb_device * * list = NULL ;
ssize_t cnt , i ;
do {
cnt = libusb_get_device_list ( NULL , & list ) ;
cnt = libusb_get_device_list ( NULL , & list ) ;
if ( unlikely ( cnt < 0 ) ) {
if ( unlikely ( cnt < 0 ) ) {
applog ( LOG_ERR , " Ztex scan devices: Failed to list usb devices with err %d " , cnt ) ;
applog ( LOG_ERR , " Ztex scan devices: Failed to list usb devices with err %d " , cnt ) ;
return 0 ;
goto done ;
}
}
for ( i = 0 ; i < cnt ; i + + ) {
for ( found = rescan = i = 0 ; i < cnt ; i + + ) {
if ( libztex_checkDevice ( list [ i ] ) ) {
err = libztex_checkDevice ( list [ i ] ) ;
switch ( err ) {
case CHECK_ERROR :
applog ( LOG_ERR , " Ztex: Can not check device: %s " , libusb_error_name ( err ) ) ;
continue ;
case CHECK_IS_NOT_ZTEX :
continue ;
case CHECK_OK :
// Got one!
// Got one!
usbdevices [ found ] = i ;
usbdevices [ found + + ] = i ;
break ;
case CHECK_RESCAN :
rescan = 1 ;
found + + ;
found + + ;
break ;
}
}
}
}
if ( found < max_found )
rescan = 1 ;
else if ( found > max_found )
max_found = found ;
if ( rescan )
libusb_free_device_list ( list , 1 ) ;
} while ( rescan ) ;
if ( 0 = = found )
goto done ;
devs = malloc ( sizeof ( struct libztex_dev_list * ) * found ) ;
devs = malloc ( sizeof ( struct libztex_dev_list * ) * found ) ;
if ( devs = = NULL ) {
if ( devs = = NULL ) {
applog ( LOG_ERR , " Ztex scan devices: Failed to allocate memory " ) ;
applog ( LOG_ERR , " Ztex scan devices: Failed to allocate memory " ) ;
return 0 ;
goto done ;
}
}
for ( i = 0 ; i < found ; i + + ) {
for ( i = 0 ; i < found ; i + + ) {
if ( ! ztex ) {
ztex = malloc ( sizeof ( * ztex ) ) ;
if ( ! ztex ) {
applog ( LOG_ERR , " %s: Can not allocate memory for device struct: %s " , __func__ , strerror ( errno ) ) ;
goto done ;
}
}
ztex - > bitFileName = NULL ;
ztex - > numberOfFpgas = - 1 ;
ztex - > valid = false ;
err = libztex_prepare_device ( list [ usbdevices [ i ] ] , & ztex ) ;
err = libztex_prepare_device ( list [ usbdevices [ i ] ] , & ztex ) ;
if ( unlikely ( err ! = 0 ) )
if ( unlikely ( err ! = 0 ) ) {
applog ( LOG_ERR , " prepare device: %d " , err ) ;
applog ( LOG_ERR , " prepare device: %d " , err ) ;
// check if valid
if ( ! ztex - > valid ) {
libztex_destroy_device ( ztex ) ;
libztex_destroy_device ( ztex ) ;
ztex = NULL ;
continue ;
continue ;
}
}
devs [ pos ] = malloc ( sizeof ( struct libztex_dev_list ) ) ;
devs [ pos ] = malloc ( sizeof ( struct libztex_dev_list ) ) ;
if ( NULL = = devs [ pos ] ) {
applog ( LOG_ERR , " %s: Can not allocate memory for device: %s " , __func__ , strerror ( errno ) ) ;
libztex_destroy_device ( ztex ) ;
ztex = NULL ;
continue ;
}
devs [ pos ] - > dev = ztex ;
devs [ pos ] - > dev = ztex ;
ztex = NULL ;
devs [ pos ] - > next = NULL ;
devs [ pos ] - > next = NULL ;
if ( pos > 0 )
if ( pos > 0 )
devs [ pos - 1 ] - > next = devs [ pos ] ;
devs [ pos - 1 ] - > next = devs [ pos ] ;
pos + + ;
pos + + ;
}
}
libusb_free_device_list ( list , 1 ) ;
ret = pos ;
done :
if ( ret > 0 )
* devs_p = devs ;
* devs_p = devs ;
return pos ;
else if ( devs )
free ( devs ) ;
if ( list )
libusb_free_device_list ( list , 1 ) ;
return ret ;
}
}
int libztex_sendHashData ( struct libztex_device * ztex , unsigned char * sendbuf )
int libztex_sendHashData ( struct libztex_device * ztex , unsigned char * sendbuf )