@ -6,6 +6,10 @@
@@ -6,6 +6,10 @@
* under the terms of the GNU General Public License as published by the Free
* Software Foundation ; either version 3 of the License , or ( at your option )
* any later version . See COPYING for more details .
*
* Note : the code always includes GPU support even if there are no GPUs
* this simplifies handling multiple other device code being included
* depending on compile options
*/
# include "config.h"
@ -134,12 +138,13 @@
@@ -134,12 +138,13 @@
# endif
// Big enough for largest API request
// though a PC with 100s of CPUs may exceed the size ...
// though a PC with 100s of PGAs/ CPUs may exceed the size ...
// Current code assumes it can socket send this size also
# define MYBUFSIZ 32768
# define MYBUFSIZ 32768 // TODO: intercept before it's exceeded
// Number of requests to queue - normally would be small
# define QUEUE 10
// However lots of PGA's may mean more
# define QUEUE 100
static char * io_buffer = NULL ;
static char * msg_buffer = NULL ;
@ -152,7 +157,7 @@ static const char *COMMA = ",";
@@ -152,7 +157,7 @@ static const char *COMMA = ",";
static const char SEPARATOR = ' | ' ;
static const char GPUSEP = ' , ' ;
static const char * APIVERSION = " 1.4 " ;
static const char * APIVERSION = " 1.5 " ;
static const char * DEAD = " Dead " ;
static const char * SICK = " Sick " ;
static const char * NOSTART = " NoStart " ;
@ -170,14 +175,19 @@ static const char *NO = "N";
@@ -170,14 +175,19 @@ static const char *NO = "N";
# define _STATUS "STATUS"
# define _VERSION "VERSION"
# define _MINECON "CONFIG"
# define _GPU "GPU"
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
# define _PGA "PGA"
# endif
# ifdef WANT_CPUMINE
# define _CPU "CPU"
# endif
# define _GPU "GPU"
# define _CPUS "CPUS"
# define _GPUS "GPUS"
# define _PGAS "PGAS"
# define _CPUS "CPUS"
# define _BYE "BYE"
static const char ISJSON = ' { ' ;
@ -196,11 +206,16 @@ static const char ISJSON = '{';
@@ -196,11 +206,16 @@ static const char ISJSON = '{';
# define JSON_MINECON JSON1 _MINECON JSON2
# define JSON_GPU JSON1 _GPU JSON2
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
# define JSON_PGA JSON1 _PGA JSON2
# endif
# ifdef WANT_CPUMINE
# define JSON_CPU JSON1 _CPU JSON2
# endif
# define JSON_GPUS JSON1 _GPUS JSON2
# define JSON_PGAS JSON1 _PGAS JSON2
# define JSON_CPUS JSON1 _CPUS JSON2
# define JSON_BYE JSON1 _BYE JSON1
# define JSON_CLOSE JSON3
@ -269,6 +284,14 @@ static const char *JSON_PARAMETER = "parameter";
@@ -269,6 +284,14 @@ static const char *JSON_PARAMETER = "parameter";
# define MSG_TOOMANYP 54
# define MSG_ADDPOOL 55
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
# define MSG_PGANON 56
# define MSG_PGADEV 57
# define MSG_INVPGA 58
# endif
# define MSG_NUMPGA 59
enum code_severity {
SEVERITY_ERR ,
SEVERITY_WARN ,
@ -279,16 +302,17 @@ enum code_severity {
@@ -279,16 +302,17 @@ enum code_severity {
enum code_parameters {
PARAM_GPU ,
PARAM_PGA ,
PARAM_CPU ,
PARAM_GPUMAX ,
PARAM_PGAMAX ,
PARAM_CPUMAX ,
PARAM_PMAX ,
PARAM_POOLMAX ,
# ifdef WANT_CPUMINE
PARAM_GCMAX ,
# else
PARAM_GMAX ,
# endif
// Single generic case: have the code resolve it - see below
PARAM_DMAX ,
PARAM_CMD ,
PARAM_POOL ,
PARAM_STR ,
@ -310,25 +334,43 @@ struct CODES {
@@ -310,25 +334,43 @@ struct CODES {
{ SEVERITY_ERR , MSG_GPUNON , PARAM_NONE , " No GPUs " } ,
{ SEVERITY_SUCC , MSG_POOL , PARAM_PMAX , " %d Pool(s) " } ,
{ SEVERITY_ERR , MSG_NOPOOL , PARAM_NONE , " No pools " } ,
{ SEVERITY_SUCC , MSG_DEVS , PARAM_DMAX , " %d GPU(s) "
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
" - %d PGA(s) "
# endif
# ifdef WANT_CPUMINE
{ SEVERITY_SUCC , MSG_DEVS , PARAM_GCMAX , " %d GPU(s) - %d CPU(s) " } ,
{ SEVERITY_ERR , MSG_NODEVS , PARAM_NONE , " No GPUs/CPUs " } ,
# else
{ SEVERITY_SUCC , MSG_DEVS , PARAM_GMAX , " %d GPU(s) " } ,
{ SEVERITY_ERR , MSG_NODEVS , PARAM_NONE , " No GPUs " } ,
" - %d CPU(s) "
# endif
} ,
{ SEVERITY_ERR , MSG_NODEVS , PARAM_NONE , " No GPUs "
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
" /PGAs "
# endif
# ifdef WANT_CPUMINE
" /CPUs "
# endif
} ,
{ SEVERITY_SUCC , MSG_SUMM , PARAM_NONE , " Summary " } ,
{ SEVERITY_INFO , MSG_GPUDIS , PARAM_GPU , " GPU %d set disable flag " } ,
{ SEVERITY_INFO , MSG_GPUREI , PARAM_GPU , " GPU %d restart attempted " } ,
{ SEVERITY_ERR , MSG_INVCMD , PARAM_NONE , " Invalid command " } ,
{ SEVERITY_ERR , MSG_MISID , PARAM_NONE , " Missing device id parameter " } ,
{ SEVERITY_SUCC , MSG_GPUDEV , PARAM_GPU , " GPU%d " } ,
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
{ SEVERITY_ERR , MSG_PGANON , PARAM_NONE , " No PGAs " } ,
{ SEVERITY_SUCC , MSG_PGADEV , PARAM_PGA , " PGA%d " } ,
{ SEVERITY_ERR , MSG_INVPGA , PARAM_PGAMAX , " Invalid PGA id %d - range is 0 - %d " } ,
# endif
# ifdef WANT_CPUMINE
{ SEVERITY_ERR , MSG_CPUNON , PARAM_NONE , " No CPUs " } ,
{ SEVERITY_SUCC , MSG_CPUDEV , PARAM_CPU , " CPU%d " } ,
{ SEVERITY_ERR , MSG_INVCPU , PARAM_CPUMAX , " Invalid CPU id %d - range is 0 - %d " } ,
# endif
{ SEVERITY_SUCC , MSG_NUMGPU , PARAM_NONE , " GPU count " } ,
{ SEVERITY_SUCC , MSG_NUMPGA , PARAM_NONE , " PGA count " } ,
{ SEVERITY_SUCC , MSG_NUMCPU , PARAM_NONE , " CPU count " } ,
{ SEVERITY_SUCC , MSG_VERSION , PARAM_NONE , " CGMiner versions " } ,
{ SEVERITY_ERR , MSG_INVJSON , PARAM_NONE , " Invalid JSON " } ,
@ -382,6 +424,54 @@ struct IP4ACCESS {
@@ -382,6 +424,54 @@ struct IP4ACCESS {
static struct IP4ACCESS * ipaccess = NULL ;
static int ips = 0 ;
# ifdef USE_BITFORCE
extern struct device_api bitforce_api ;
# endif
# ifdef USE_ICARUS
extern struct device_api icarus_api ;
# endif
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
static int numpgas ( )
{
int count = 0 ;
int i ;
for ( i = 0 ; i < total_devices ; i + + ) {
# ifdef USE_BITFORCE
if ( devices [ i ] - > api = = & bitforce_api )
count + + ;
# endif
# ifdef USE_ICARUS
if ( devices [ i ] - > api = = & icarus_api )
count + + ;
# endif
}
return count ;
}
static int pgadevice ( int pgaid )
{
int count = 0 ;
int i ;
for ( i = 0 ; i < total_devices ; i + + ) {
# ifdef USE_BITFORCE
if ( devices [ i ] - > api = = & bitforce_api )
count + + ;
# endif
# ifdef USE_ICARUS
if ( devices [ i ] - > api = = & icarus_api )
count + + ;
# endif
if ( count = = ( pgaid + 1 ) )
return i ;
}
return - 1 ;
}
# endif
// All replies (except BYE) start with a message
// thus for JSON, message() inserts JSON_START at the front
// and send_result() adds JSON_END at the end
@ -389,6 +479,9 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
@@ -389,6 +479,9 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
{
char severity ;
char * ptr ;
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
int pga ;
# endif
# ifdef WANT_CPUMINE
int cpu ;
# endif
@ -421,6 +514,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
@@ -421,6 +514,7 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
switch ( codes [ i ] . params ) {
case PARAM_GPU :
case PARAM_PGA :
case PARAM_CPU :
sprintf ( ptr , codes [ i ] . description , paramid ) ;
break ;
@ -436,20 +530,26 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
@@ -436,20 +530,26 @@ static char *message(int messageid, int paramid, char *param2, bool isjson)
case PARAM_POOLMAX :
sprintf ( ptr , codes [ i ] . description , paramid , total_pools - 1 ) ;
break ;
case PARAM_DMAX :
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
pga = numpgas ( ) ;
# endif
# ifdef WANT_CPUMINE
case PARAM_GCMAX :
if ( opt_n_threads > 0 )
cpu = num_processors ;
else
cpu = 0 ;
# endif
sprintf ( ptr , codes [ i ] . description , nDevs , cpu ) ;
break ;
# else
case PARAM_GMAX :
sprintf ( ptr , codes [ i ] . description , nDevs ) ;
break ;
sprintf ( ptr , codes [ i ] . description , nDevs
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
, pga
# endif
# ifdef WANT_CPUMINE
, cpu
# endif
) ;
break ;
case PARAM_CMD :
sprintf ( ptr , codes [ i ] . description , JSON_COMMAND ) ;
break ;
@ -500,6 +600,7 @@ static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -500,6 +600,7 @@ static void apiversion(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
static void minerconfig ( __maybe_unused SOCKETTYPE c , __maybe_unused char * param , bool isjson )
{
char buf [ BUFSIZ ] ;
int pgacount = 0 ;
int cpucount = 0 ;
char * adlinuse = ( char * ) NO ;
# ifdef HAVE_ADL
@ -516,6 +617,10 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -516,6 +617,10 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
const char * adl = NO ;
# endif
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
pgacount = numpgas ( ) ;
# endif
# ifdef WANT_CPUMINE
cpucount = opt_n_threads > 0 ? num_processors : 0 ;
# endif
@ -523,9 +628,9 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
@@ -523,9 +628,9 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
strcpy ( io_buffer , message ( MSG_MINECON , 0 , NULL , isjson ) ) ;
if ( isjson )
sprintf ( buf , " , " JSON_MINECON " { \" GPU Count \" :%d, \" CPU Count \" :%d, \" Pool Count \" :%d, \" ADL \" : \" %s \" , \" ADL in use \" : \" %s \" , \" Strategy \" : \" %s \" , \" Log Interval \" : \" %d \" } " JSON_CLOSE , nDevs , cpucount , total_pools , adl , adlinuse , strategies [ pool_strategy ] . s , opt_log_interval ) ;
sprintf ( buf , " , " JSON_MINECON " { \" GPU Count \" :%d, \" PGA Count \" :%d, \" CPU Count \" :%d, \" Pool Count \" :%d, \" ADL \" : \" %s \" , \" ADL in use \" : \" %s \" , \" Strategy \" : \" %s \" , \" Log Interval \" : \" %d \" } " JSON_CLOSE , nDevs , pgacount , cpucount , total_pools , adl , adlinuse , strategies [ pool_strategy ] . s , opt_log_interval ) ;
else
sprintf ( buf , _MINECON " ,GPU Count=%d,CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d%c " , nDevs , cpucount , total_pools , adl , adlinuse , strategies [ pool_strategy ] . s , opt_log_interval , SEPARATOR ) ;
sprintf ( buf , _MINECON " ,GPU Count=%d,PGA Count=%d, CPU Count=%d,Pool Count=%d,ADL=%s,ADL in use=%s,Strategy=%s,Log Interval=%d%c " , nDevs , pgacount , cpucount , total_pools , adl , adlinuse , strategies [ pool_strategy ] . s , opt_log_interval , SEPARATOR ) ;
strcat ( io_buffer , buf ) ;
}
@ -589,6 +694,59 @@ static void gpustatus(int gpu, bool isjson)
@@ -589,6 +694,59 @@ static void gpustatus(int gpu, bool isjson)
}
}
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
static void pgastatus ( int pga , bool isjson )
{
char buf [ BUFSIZ ] ;
char * enabled ;
char * status ;
int numpga = numpgas ( ) ;
if ( numpga > 0 & & pga > = 0 & & pga < numpga ) {
int dev = pgadevice ( pga ) ;
if ( dev < 0 ) // Should never happen
return ;
struct cgpu_info * cgpu = devices [ dev ] ;
cgpu - > utility = cgpu - > accepted / ( total_secs ? total_secs : 1 ) * 60 ;
if ( cgpu - > deven ! = DEV_DISABLED )
enabled = ( char * ) YES ;
else
enabled = ( char * ) NO ;
if ( cgpu - > status = = LIFE_DEAD )
status = ( char * ) DEAD ;
else if ( cgpu - > status = = LIFE_SICK )
status = ( char * ) SICK ;
else if ( cgpu - > status = = LIFE_NOSTART )
status = ( char * ) NOSTART ;
else
status = ( char * ) ALIVE ;
if ( isjson )
sprintf ( buf , " { \" PGA \" :%d, \" Name \" : \" %s \" , \" ID \" :%d, \" Enabled \" : \" %s \" , \" Status \" : \" %s \" , \" Temperature \" :%.2f, \" MHS av \" :%.2f, \" MHS %ds \" :%.2f, \" Accepted \" :%d, \" Rejected \" :%d, \" Hardware Errors \" :%d, \" Utility \" :%.2f, \" Last Share Pool \" :%d, \" Last Share Time \" :%lu, \" Total MH \" :%.4f} " ,
pga , cgpu - > api - > name , cgpu - > device_id ,
enabled , status , cgpu - > temp ,
cgpu - > total_mhashes / total_secs , opt_log_interval , cgpu - > rolling ,
cgpu - > accepted , cgpu - > rejected , cgpu - > hw_errors , cgpu - > utility ,
( ( unsigned long ) ( cgpu - > last_share_pool_time ) > 0 ) ? cgpu - > last_share_pool : - 1 ,
( unsigned long ) ( cgpu - > last_share_pool_time ) , cgpu - > total_mhashes ) ;
else
sprintf ( buf , " PGA=%d,Name=%s,ID=%d,Enabled=%s,Status=%s,Temperature=%.2f,MHS av=%.2f,MHS %ds=%.2f,Accepted=%d,Rejected=%d,Hardware Errors=%d,Utility=%.2f,Last Share Pool=%d,Last Share Time=%lu,Total MH=%.4f%c " ,
pga , cgpu - > api - > name , cgpu - > device_id ,
enabled , status , cgpu - > temp ,
cgpu - > total_mhashes / total_secs , opt_log_interval , cgpu - > rolling ,
cgpu - > accepted , cgpu - > rejected , cgpu - > hw_errors , cgpu - > utility ,
( ( unsigned long ) ( cgpu - > last_share_pool_time ) > 0 ) ? cgpu - > last_share_pool : - 1 ,
( unsigned long ) ( cgpu - > last_share_pool_time ) , cgpu - > total_mhashes , SEPARATOR ) ;
strcat ( io_buffer , buf ) ;
}
}
# endif
# ifdef WANT_CPUMINE
static void cpustatus ( int cpu , bool isjson )
{
@ -623,6 +781,7 @@ static void cpustatus(int cpu, bool isjson)
@@ -623,6 +781,7 @@ static void cpustatus(int cpu, bool isjson)
static void devstatus ( __maybe_unused SOCKETTYPE c , __maybe_unused char * param , bool isjson )
{
int devcount = 0 ;
int i ;
if ( nDevs = = 0 & & opt_n_threads = = 0 ) {
@ -638,19 +797,37 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
@@ -638,19 +797,37 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
}
for ( i = 0 ; i < nDevs ; i + + ) {
if ( isjson & & i > 0 )
if ( isjson & & devcount > 0 )
strcat ( io_buffer , COMMA ) ;
gpustatus ( i , isjson ) ;
devcount + + ;
}
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
int numpga = numpgas ( ) ;
if ( numpga > 0 )
for ( i = 0 ; i < numpga ; i + + ) {
if ( isjson & & devcount > 0 )
strcat ( io_buffer , COMMA ) ;
pgastatus ( i , isjson ) ;
devcount + + ;
}
# endif
# ifdef WANT_CPUMINE
if ( opt_n_threads > 0 )
for ( i = 0 ; i < num_processors ; i + + ) {
if ( isjson & & ( i > 0 | | nDevs > 0 ) )
if ( isjson & & devcount > 0 )
strcat ( io_buffer , COMMA ) ;
cpustatus ( i , isjson ) ;
devcount + + ;
}
# endif
@ -691,6 +868,42 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
@@ -691,6 +868,42 @@ static void gpudev(__maybe_unused SOCKETTYPE c, char *param, bool isjson)
strcat ( io_buffer , JSON_CLOSE ) ;
}
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
static void pgadev ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
{
int numpga = numpgas ( ) ;
int id ;
if ( numpga = = 0 ) {
strcpy ( io_buffer , message ( MSG_PGANON , 0 , NULL , isjson ) ) ;
return ;
}
if ( param = = NULL | | * param = = ' \0 ' ) {
strcpy ( io_buffer , message ( MSG_MISID , 0 , NULL , isjson ) ) ;
return ;
}
id = atoi ( param ) ;
if ( id < 0 | | id > = numpga ) {
strcpy ( io_buffer , message ( MSG_INVPGA , id , NULL , isjson ) ) ;
return ;
}
strcpy ( io_buffer , message ( MSG_PGADEV , id , NULL , isjson ) ) ;
if ( isjson ) {
strcat ( io_buffer , COMMA ) ;
strcat ( io_buffer , JSON_PGA ) ;
}
pgastatus ( id , isjson ) ;
if ( isjson )
strcat ( io_buffer , JSON_CLOSE ) ;
}
# endif
# ifdef WANT_CPUMINE
static void cpudev ( __maybe_unused SOCKETTYPE c , char * param , bool isjson )
{
@ -949,6 +1162,25 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
@@ -949,6 +1162,25 @@ static void gpucount(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bo
strcat ( io_buffer , buf ) ;
}
static void pgacount ( __maybe_unused SOCKETTYPE c , __maybe_unused char * param , bool isjson )
{
char buf [ BUFSIZ ] ;
int count = 0 ;
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
count = numpgas ( ) ;
# endif
strcpy ( io_buffer , message ( MSG_NUMPGA , 0 , NULL , isjson ) ) ;
if ( isjson )
sprintf ( buf , " , " JSON_PGAS " { \" Count \" :%d} " JSON_CLOSE , count ) ;
else
sprintf ( buf , _PGAS " ,Count=%d%c " , count , SEPARATOR ) ;
strcat ( io_buffer , buf ) ;
}
static void cpucount ( __maybe_unused SOCKETTYPE c , __maybe_unused char * param , bool isjson )
{
char buf [ BUFSIZ ] ;
@ -1350,10 +1582,14 @@ struct CMDS {
@@ -1350,10 +1582,14 @@ struct CMDS {
{ " gpudisable " , gpudisable , true } ,
{ " gpurestart " , gpurestart , true } ,
{ " gpu " , gpudev , false } ,
# if defined(USE_BITFORCE) || defined(USE_ICARUS)
{ " pga " , pgadev , false } ,
# endif
# ifdef WANT_CPUMINE
{ " cpu " , cpudev , false } ,
# endif
{ " gpucount " , gpucount , false } ,
{ " pgacount " , pgacount , false } ,
{ " cpucount " , cpucount , false } ,
{ " switchpool " , switchpool , true } ,
{ " addpool " , addpool , true } ,