Browse Source

Merge branch 'master' of git://github.com/ckolivas/cgminer.git

nfactor-troky
Paul Sheppard 12 years ago
parent
commit
736c62a91e
  1. 49
      API-README
  2. 23
      FPGA-README
  3. 3
      Makefile.am
  4. 74
      NEWS
  5. 2
      README
  6. 30
      adl.c
  7. 60
      api.c
  8. 108
      bitforce-firmware-flash.c
  9. 242
      cgminer.c
  10. 12
      configure.ac
  11. 51
      diablo120823.cl
  12. 47
      diakgcn120823.cl
  13. 2
      driver-bitforce.c
  14. 93
      driver-opencl.c
  15. 1
      example.conf
  16. 17
      findnonce.c
  17. 5
      findnonce.h
  18. 6
      miner.h
  19. 25
      miner.php
  20. 162
      mkinstalldirs
  21. 11
      ocl.c
  22. 51
      phatk120823.cl
  23. 51
      poclbm120823.cl
  24. 13
      scrypt120823.cl
  25. 39
      windows-build.txt

49
API-README

@ -42,7 +42,7 @@ To give an IP address/subnet access to a group you use the group letter
in front of the IP address instead of W: e.g. P:192.168.0/32 in front of the IP address instead of W: e.g. P:192.168.0/32
An IP address/subnet can only be a member of one group An IP address/subnet can only be a member of one group
A sample API group would be: A sample API group would be:
--api-groups P:switchpool:enablepool:addpool:disablepool:removepool.poolpriority:* --api-groups P:switchpool:enablepool:addpool:disablepool:removepool:poolpriority:*
This would create a group 'P' that can do all current pool commands and all This would create a group 'P' that can do all current pool commands and all
non-priviliged commands - the '*' means all non-priviledged commands non-priviliged commands - the '*' means all non-priviledged commands
Without the '*' the group would only have access to the pool commands Without the '*' the group would only have access to the pool commands
@ -281,6 +281,12 @@ The list of requests - a (*) means it requires privileged access - and replies a
none There is no reply section just the STATUS section none There is no reply section just the STATUS section
stating what failover-only was set to stating what failover-only was set to
coin COIN Coin mining information:
Hash Method=sha256/scrypt,
Current Block Time=N.N, <- 0 means none
Current Block Hash=XXXX..., <- blank if none
LP=true/false| <- LP is in use on at least 1 pool
When you enable, disable or restart a GPU or PGA, you will also get Thread messages When you enable, disable or restart a GPU or PGA, you will also get Thread messages
in the cgminer status window in the cgminer status window
@ -333,7 +339,10 @@ miner.php - an example web page to access the API
Feature Changelog for external applications using the API: Feature Changelog for external applications using the API:
API V1.17 API V1.17 (cgminer v2.7.1)
Added API commands:
'coin'
Modified API commands: Modified API commands:
'summary' - add 'Work Utility' 'summary' - add 'Work Utility'
@ -745,6 +754,31 @@ Below is each variable that can be changed and an explanation of each
--------- ---------
Default:
$dfmt = 'H:i:s j-M-Y \U\T\CP';
Define the date format used to print full length dates
If you get the string 'UTCP' on the end of your dates shown, that
means you are using an older version of PHP and you can instead use:
$dfmt = 'H:i:s j-M-Y \U\T\CO';
The PHP documentation on the date format is here:
http://us.php.net/manual/en/function.date.php
---------
Default:
$title = 'Mine';
Web page title
If you know PHP you can of course use code to define it e.g.
$title = 'My Rig at: '.date($dfmt);
Which would set the web page title to something like:
My Rig at: 10:34:00 22-Aug-2012 UTC+10:00
---------
Default: Default:
$readonly = false; $readonly = false;
@ -948,7 +982,7 @@ The section defines what data you want in the summary table and the Fields
define what data you want shown from that section define what data you want shown from that section
Standard sections are: Standard sections are:
SUMMARY, POOL, PGA, GPU, NOTIFY, CONFIG, DEVDETAILS, DEVS, STATS SUMMARY, POOL, PGA, GPU, NOTIFY, CONFIG, DEVDETAILS, DEVS, STATS, COIN
Fields are the names as shown on the headers on the normal pages Fields are the names as shown on the headers on the normal pages
@ -957,6 +991,7 @@ Fields can be 'name=new name' to display 'name' with a different heading
There are also now joined sections: There are also now joined sections:
SUMMARY+POOL, SUMMARY+DEVS, SUMMARY+CONFIG, DEVS+NOTIFY, DEVS+DEVDETAILS SUMMARY+POOL, SUMMARY+DEVS, SUMMARY+CONFIG, DEVS+NOTIFY, DEVS+DEVDETAILS
SUMMARY+COIN
These sections are an SQL join of the two sections and the fields in them These sections are an SQL join of the two sections and the fields in them
are named section.field where section. is the section the field comes from are named section.field where section. is the section the field comes from
@ -967,11 +1002,11 @@ Also note:
- empty columns (e.g. an unknown field) are not shown - empty columns (e.g. an unknown field) are not shown
- missing field data shows as blank - missing field data shows as blank
- the field name '*' matches all fields except in joined sections - the field name '*' matches all fields except in joined sections
(useful for STATS) (useful for STATS and COIN)
There are 2 hard coded sections: There are 2 hard coded sections:
DATE - displays a date table like 'Summary' DATE - displays a date table like at the start of 'Summary'
RIGS - displays a rig table like 'Summary' RIGS - displays a rig table like at the start of 'Summary'
Each custom summary requires a second array, that can be empty, listing fields Each custom summary requires a second array, that can be empty, listing fields
to be totaled for each section to be totaled for each section
@ -1028,7 +1063,7 @@ Each table will have the chosen details for all the rigs specified in $rigs
section.fieldname, not just fieldname section.fieldname, not just fieldname
The join code automatically adds 2 fields to each GPU device: 'Name' and 'ID' The join code automatically adds 2 fields to each GPU device: 'Name' and 'ID'
They don't exist in the API 'devs' output but you can correctly calculate They don't exist in the API 'devs' output but I can correctly calculate
them from the GPU device data them from the GPU device data
These two fields are used to join DEVS to NOTIFY i.e. find the NOTIFY These two fields are used to join DEVS to NOTIFY i.e. find the NOTIFY
record that has the same Name and ID as the DEVS record and join them record that has the same Name and ID as the DEVS record and join them

23
FPGA-README

@ -1,6 +1,7 @@
This README contains extended details about FPGA mining with cgminer This README contains extended details about FPGA mining with cgminer
Bitforce Bitforce
--bfl-range Use nonce range on bitforce devices if supported --bfl-range Use nonce range on bitforce devices if supported
@ -13,6 +14,28 @@ a cost of 1% in overall hashrate so this feature is disabled by default. It
is only recommended you enable this if you are mining with a minirig on is only recommended you enable this if you are mining with a minirig on
p2pool. p2pool.
C source is included for a bitforce firmware flash utility on Linux only:
bitforce-firmware-flash.c
Using this, you can change the bitstream firmware on bitforce singles.
It is untested with other devices. Use at your own risk!
To compile:
make bitforce-firmware-flash
To flash your BFL, specify the BFL port and the flash file e.g.:
sudo ./bitforce-firmware-flash /dev/ttyUSB0 alphaminer_832.bfl
It takes a bit under 3 minutes to flash a BFL and shows a progress % counter
Once it completes, you may also need to wait about 15 seconds,
then power the BFL off and on again
If you get an error at the end of the BFL flash process stating:
"Error reading response from ZBX"
it may have worked successfully anyway.
Test mining on it to be sure if it worked or not.
You need to give cgminer about 10 minutes mining with the BFL to be sure of
the MH/s value reported with the changed firmware - and the MH/s reported
will be less than the firmware speed since you lose work on every block change.
Icarus Icarus

3
Makefile.am

@ -10,7 +10,8 @@ endif
EXTRA_DIST = example.conf m4/gnulib-cache.m4 linux-usb-cgminer \ EXTRA_DIST = example.conf m4/gnulib-cache.m4 linux-usb-cgminer \
ADL_SDK/readme.txt api-example.php miner.php \ ADL_SDK/readme.txt api-example.php miner.php \
API.class API.java api-example.c windows-build.txt \ API.class API.java api-example.c windows-build.txt \
bitstreams/* API-README FPGA-README SCRYPT-README bitstreams/* API-README FPGA-README SCRYPT-README \
bitforce-firmware-flash.c
SUBDIRS = lib compat ccan SUBDIRS = lib compat ccan

74
NEWS

@ -1,3 +1,77 @@
Version 2.7.2 - August 22, 2012
- Pick worksize 256 with Cypress if none is specified.
- Give warning with sdk2.7 and phatk as well.
- Whitelist sdk2.7 for diablo kernel as well.
- Only keep the last 6 blocks in the uthash database to keep memory usage
constant. Storing more is unhelpful anyway.
- BFL Flash - always distribute source
- Increase kernel versions signifying changed APIs.
- BFL flash - include source in builds and more FPGA-README
- Check we haven't staged work while waiting for a curl entry before proceeding.
- Use atomic ops to never miss a nonce on opencl kernels, including nonce==0,
also allowing us to make the output buffer smaller.
- Remove compile errors/warnings and document compile/usage in FPGA-README
- bitforce-firmware-flash.c by Luke-jr
- Ignore the submit_fail flag when deciding whether to recruit more curls or not
since we have upper bounds on how many curls can be recruited, this test is
redundant and can lead to problems.
- API-README update cgminer version number
- API-README fix groups P: example mistake
- API-README add COIN and other edits
- gpu->hit should be reset on new work as well.
- Do not add time to dynamic opencl calculations over a getwork.
- miner.php allow 'coin' is custom pages
Version 2.7.1 - August 21, 2012
- Update windows build instructions courtesy of sharky.
- Increase max curls to number of mining threads + queue * 2, accounting for up
and downstream comms.
- Queue enough requests to get started.
- There is no point trying to clone_work in get_work() any more since we clone
on every get_work_thread where possible.
- There is no point subtracting 1 from maxq in get_work_thread.
- Only set lagging flag once there are no staged work items.
- select_pool does not switch back to the primary once lagging is disabled.
- miner.php allow page title to be defined in myminer.php
- Free work before retrying in get_work_thread.
- Increment total work counter under mutex lock.
- Increment the queued count after the curl is popped in case there's a delay
waiting on curls and we think we've queued work when in fact we're waiting
- API new command 'coin' with mining information
- Do the dynamic timing in opencl code over a single pass through scanhash to
make sure we're only getting opencl times contributing to the measured inte
- Increase curl reaping time to 5 minutes since comms between curl requests can
be 2 mins apart with lots of rolltime.
- No need for extra variable in hash_push.
- Remove short options -r and -R to allow them to be reused and remove readme
entries for deprecated options.
- Avoid attempting to recursively lock the console mutex by disabling warnings
in gpu_fanpercent when fanspeed monitoring fails on windows. Debugged by l
- Deprecate the opt_fail_pause parameter, leaving a null placeholder for
existing configurations.
- Don't pause after failed getwork, set lagging flag and reassess.
- Add message to share if it's a resubmit.
- We should not be pausing in trying to resubmit shares.
- Get rid of the extending fail pause on failed connects since we discard work
after a period.
- get_work always returns true so turn it into a void function.
- get_work never returns false so get rid of fail pause loop.
- Get rid of pause and retry from get_upstream_work so we only do it from one
place.
- Deprecate the opt_retries feature as no one wants cgminer to automatically
abort. Leave a null placeholder for configurations that still have it.
- Reinstate fix ADL gpu-map not working when there are more ADL devices than
openCL patch by Nite69. Add virtual adl mapping for when none is specified o
- miner.php show summary Diff1 Shares total
- miner.php fix Work Utility totals
- miner.php format new Work Utility and Diff1 Shares
- API V1.17 show Work Utility and Diff1 Shares
Version 2.7.0 - August 18, 2012 Version 2.7.0 - August 18, 2012
- Introduce a new statistic, Work Utility, which is the number of difficulty 1 - Introduce a new statistic, Work Utility, which is the number of difficulty 1

2
README

@ -160,8 +160,6 @@ Options for both config file and command line:
--quiet|-q Disable logging output, display status and errors --quiet|-q Disable logging output, display status and errors
--real-quiet Disable all output --real-quiet Disable all output
--remove-disabled Remove disabled devices entirely, as if they didn't exist --remove-disabled Remove disabled devices entirely, as if they didn't exist
--retries|-r <arg> Number of times to retry before giving up, if JSON-RPC call fails (-1 means never) (default: -1)
--retry-pause|-R <arg> Number of seconds to pause, between retries (default: 5)
--rotate <arg> Change multipool strategy from failover to regularly rotate at N minutes (default: 0) --rotate <arg> Change multipool strategy from failover to regularly rotate at N minutes (default: 0)
--round-robin Change multipool strategy from failover to round robin on failure --round-robin Change multipool strategy from failover to round robin on failure
--scan-time|-s <arg> Upper bound on time spent scanning current work, in seconds (default: 60) --scan-time|-s <arg> Upper bound on time spent scanning current work, in seconds (default: 60)

30
adl.c

@ -306,7 +306,8 @@ void init_adl(int nDevs)
if (gpus[i].mapped) { if (gpus[i].mapped) {
vadapters[gpus[i].virtual_adl].virtual_gpu = i; vadapters[gpus[i].virtual_adl].virtual_gpu = i;
applog(LOG_INFO, "Mapping OpenCL device %d to ADL device %d", i, gpus[i].virtual_adl); applog(LOG_INFO, "Mapping OpenCL device %d to ADL device %d", i, gpus[i].virtual_adl);
} } else
gpus[i].virtual_adl = i;
} }
if (!devs_match) { if (!devs_match) {
@ -347,11 +348,12 @@ void init_adl(int nDevs)
int iAdapterIndex; int iAdapterIndex;
int lpAdapterID; int lpAdapterID;
ADLODPerformanceLevels *lpOdPerformanceLevels; ADLODPerformanceLevels *lpOdPerformanceLevels;
int lev; int lev, adlGpu;
i = vadapters[gpu].id; adlGpu = gpus[gpu].virtual_adl;
i = vadapters[adlGpu].id;
iAdapterIndex = lpInfo[i].iAdapterIndex; iAdapterIndex = lpInfo[i].iAdapterIndex;
gpus[gpu].virtual_gpu = vadapters[gpu].virtual_gpu; gpus[gpu].virtual_gpu = vadapters[adlGpu].virtual_gpu;
/* Get unique identifier of the adapter, 0 means not AMD */ /* Get unique identifier of the adapter, 0 means not AMD */
result = ADL_Adapter_ID_Get(iAdapterIndex, &lpAdapterID); result = ADL_Adapter_ID_Get(iAdapterIndex, &lpAdapterID);
@ -361,11 +363,11 @@ void init_adl(int nDevs)
} }
if (gpus[gpu].deven == DEV_DISABLED) { if (gpus[gpu].deven == DEV_DISABLED) {
gpus[i].gpu_engine = gpus[gpu].gpu_engine =
gpus[i].gpu_memclock = gpus[gpu].gpu_memclock =
gpus[i].gpu_vddc = gpus[gpu].gpu_vddc =
gpus[i].gpu_fan = gpus[gpu].gpu_fan =
gpus[i].gpu_powertune = 0; gpus[gpu].gpu_powertune = 0;
continue; continue;
} }
@ -701,6 +703,8 @@ int gpu_fanpercent(int gpu)
ret = __gpu_fanpercent(ga); ret = __gpu_fanpercent(ga);
unlock_adl(); unlock_adl();
if (unlikely(ga->has_fanspeed && ret == -1)) { if (unlikely(ga->has_fanspeed && ret == -1)) {
#if 0
/* Recursive calling applog causes a hang, so disable messages */
applog(LOG_WARNING, "GPU %d stopped reporting fanspeed due to driver corruption", gpu); applog(LOG_WARNING, "GPU %d stopped reporting fanspeed due to driver corruption", gpu);
if (opt_restart) { if (opt_restart) {
applog(LOG_WARNING, "Restart enabled, will attempt to restart cgminer"); applog(LOG_WARNING, "Restart enabled, will attempt to restart cgminer");
@ -714,6 +718,14 @@ int gpu_fanpercent(int gpu)
ga->twin->twin = NULL;; ga->twin->twin = NULL;;
ga->twin = NULL; ga->twin = NULL;
} }
#endif
if (opt_restart)
app_restart();
ga->has_fanspeed = false;
if (ga->twin) {
ga->twin->twin = NULL;;
ga->twin = NULL;
}
} }
return ret; return ret;
} }

60
api.c

@ -187,6 +187,11 @@ static const char *NULLSTR = "(null)";
static const char *TRUESTR = "true"; static const char *TRUESTR = "true";
static const char *FALSESTR = "false"; static const char *FALSESTR = "false";
#ifdef USE_SCRYPT
static const char *SCRYPTSTR = "scrypt";
#endif
static const char *SHA256STR = "sha256";
static const char *DEVICECODE = "" static const char *DEVICECODE = ""
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
"GPU " "GPU "
@ -232,7 +237,7 @@ static const char *OSINFO =
#define _SUMMARY "SUMMARY" #define _SUMMARY "SUMMARY"
#define _STATUS "STATUS" #define _STATUS "STATUS"
#define _VERSION "VERSION" #define _VERSION "VERSION"
#define _MINECON "CONFIG" #define _MINECONFIG "CONFIG"
#define _GPU "GPU" #define _GPU "GPU"
#ifdef HAVE_AN_FPGA #ifdef HAVE_AN_FPGA
@ -252,6 +257,7 @@ static const char *OSINFO =
#define _RESTART "RESTART" #define _RESTART "RESTART"
#define _MINESTATS "STATS" #define _MINESTATS "STATS"
#define _CHECK "CHECK" #define _CHECK "CHECK"
#define _MINECOIN "COIN"
static const char ISJSON = '{'; static const char ISJSON = '{';
#define JSON0 "{" #define JSON0 "{"
@ -267,7 +273,7 @@ static const char ISJSON = '{';
#define JSON_SUMMARY JSON1 _SUMMARY JSON2 #define JSON_SUMMARY JSON1 _SUMMARY JSON2
#define JSON_STATUS JSON1 _STATUS JSON2 #define JSON_STATUS JSON1 _STATUS JSON2
#define JSON_VERSION JSON1 _VERSION JSON2 #define JSON_VERSION JSON1 _VERSION JSON2
#define JSON_MINECON JSON1 _MINECON JSON2 #define JSON_MINECONFIG JSON1 _MINECONFIG JSON2
#define JSON_GPU JSON1 _GPU JSON2 #define JSON_GPU JSON1 _GPU JSON2
#ifdef HAVE_AN_FPGA #ifdef HAVE_AN_FPGA
@ -288,6 +294,7 @@ static const char ISJSON = '{';
#define JSON_CLOSE JSON3 #define JSON_CLOSE JSON3
#define JSON_MINESTATS JSON1 _MINESTATS JSON2 #define JSON_MINESTATS JSON1 _MINESTATS JSON2
#define JSON_CHECK JSON1 _CHECK JSON2 #define JSON_CHECK JSON1 _CHECK JSON2
#define JSON_MINECOIN JSON1 _MINECOIN JSON2
#define JSON_END JSON4 JSON5 #define JSON_END JSON4 JSON5
static const char *JSON_COMMAND = "command"; static const char *JSON_COMMAND = "command";
@ -329,7 +336,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_NOGPUADL 30 #define MSG_NOGPUADL 30
#define MSG_INVINT 31 #define MSG_INVINT 31
#define MSG_GPUINT 32 #define MSG_GPUINT 32
#define MSG_MINECON 33 #define MSG_MINECONFIG 33
#define MSG_GPUMERR 34 #define MSG_GPUMERR 34
#define MSG_GPUMEM 35 #define MSG_GPUMEM 35
#define MSG_GPUEERR 36 #define MSG_GPUEERR 36
@ -382,6 +389,7 @@ static const char *JSON_PARAMETER = "parameter";
#define MSG_MISBOOL 75 #define MSG_MISBOOL 75
#define MSG_INVBOOL 76 #define MSG_INVBOOL 76
#define MSG_FOO 77 #define MSG_FOO 77
#define MSG_MINECOIN 78
enum code_severity { enum code_severity {
SEVERITY_ERR, SEVERITY_ERR,
@ -496,7 +504,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" }, { SEVERITY_ERR, MSG_NOGPUADL,PARAM_GPU, "GPU %d does not have ADL" },
{ SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " _MIN_INTENSITY_STR " - " _MAX_INTENSITY_STR }, { SEVERITY_ERR, MSG_INVINT, PARAM_STR, "Invalid intensity (%s) - must be '" _DYNAMIC "' or range " _MIN_INTENSITY_STR " - " _MAX_INTENSITY_STR },
{ SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" }, { SEVERITY_INFO, MSG_GPUINT, PARAM_BOTH, "GPU %d set new intensity to %s" },
{ SEVERITY_SUCC, MSG_MINECON, PARAM_NONE, "CGMiner config" }, { SEVERITY_SUCC, MSG_MINECONFIG,PARAM_NONE, "CGMiner config" },
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
{ SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" }, { SEVERITY_ERR, MSG_GPUMERR, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported failure" },
{ SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" }, { SEVERITY_SUCC, MSG_GPUMEM, PARAM_BOTH, "Setting GPU %d memoryclock to (%s) reported success" },
@ -534,6 +542,7 @@ struct CODES {
{ SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" }, { SEVERITY_ERR, MSG_MISBOOL, PARAM_NONE, "Missing parameter: true/false" },
{ SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" }, { SEVERITY_ERR, MSG_INVBOOL, PARAM_NONE, "Invalid parameter should be true or false" },
{ SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" }, { SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" },
{ SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "CGMiner coin" },
{ SEVERITY_FAIL, 0, 0, NULL } { SEVERITY_FAIL, 0, 0, NULL }
}; };
@ -1232,9 +1241,9 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
#endif #endif
sprintf(io_buffer, isjson sprintf(io_buffer, isjson
? "%s," JSON_MINECON ? "%s," JSON_MINECONFIG
: "%s" _MINECON ",", : "%s" _MINECONFIG ",",
message(MSG_MINECON, 0, NULL, isjson)); message(MSG_MINECONFIG, 0, NULL, isjson));
root = api_add_int(root, "GPU Count", &gpucount, false); root = api_add_int(root, "GPU Count", &gpucount, false);
root = api_add_int(root, "PGA Count", &pgacount, false); root = api_add_int(root, "PGA Count", &pgacount, false);
@ -2741,6 +2750,42 @@ static void failoveronly(__maybe_unused SOCKETTYPE c, char *param, bool isjson,
strcpy(io_buffer, message(MSG_FOO, tf, NULL, isjson)); strcpy(io_buffer, message(MSG_FOO, tf, NULL, isjson));
} }
static void minecoin(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
{
struct api_data *root = NULL;
char buf[TMPBUFSIZ];
sprintf(io_buffer, isjson
? "%s," JSON_MINECOIN
: "%s" _MINECOIN ",",
message(MSG_MINECOIN, 0, NULL, isjson));
#ifdef USE_SCRYPT
if (opt_scrypt)
root = api_add_const(root, "Hash Method", SCRYPTSTR, false);
else
#endif
root = api_add_const(root, "Hash Method", SHA256STR, false);
mutex_lock(&ch_lock);
if (current_fullhash && *current_fullhash) {
root = api_add_timeval(root, "Current Block Time", &block_timeval, true);
root = api_add_string(root, "Current Block Hash", current_fullhash, true);
} else {
struct timeval t = {0,0};
root = api_add_timeval(root, "Current Block Time", &t, true);
root = api_add_const(root, "Current Block Hash", BLANK, false);
}
mutex_unlock(&ch_lock);
root = api_add_bool(root, "LP", &have_longpoll, false);
root = print_data(root, buf, isjson);
if (isjson)
strcat(buf, JSON_CLOSE);
strcat(io_buffer, buf);
}
static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); static void checkcommand(__maybe_unused SOCKETTYPE c, char *param, bool isjson, char group);
struct CMDS { struct CMDS {
@ -2792,6 +2837,7 @@ struct CMDS {
{ "stats", minerstats, false }, { "stats", minerstats, false },
{ "check", checkcommand, false }, { "check", checkcommand, false },
{ "failover-only", failoveronly, true }, { "failover-only", failoveronly, true },
{ "coin", minecoin, false },
{ NULL, NULL, false } { NULL, NULL, false }
}; };

108
bitforce-firmware-flash.c

@ -0,0 +1,108 @@
/*
* Copyright 2012 Luke Dashjr
*
* This program is free software; you can redistribute it and/or modify it
* 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.
*/
#define _BSD_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
#include <arpa/inet.h>
#define BFL_FILE_MAGIC "BFLDATA"
#define BFL_UPLOAD_MAGIC "NGH-STREAM"
#define myassert(expr, n, ...) \
do { \
if (!(expr)) { \
fprintf(stderr, __VA_ARGS__); \
return n; \
} \
} while(0)
#define ERRRESP(buf) buf, (buf[strlen(buf)-1] == '\n' ? "" : "\n")
#define WAITFOROK(n, msg) \
do { \
myassert(fgets(buf, sizeof(buf), BFL), n, "Error reading response from " msg "\n"); \
myassert(!strcmp(buf, "OK\n"), n, "Invalid response from " msg ": %s%s", ERRRESP(buf)); \
} while(0)
int main(int argc, char**argv)
{
myassert(argc == 3, 1, "Usage: %s <serialdev> <firmware.bfl>\n", argv[0]);
setbuf(stdout, NULL);
// Check filename
char *FWname = basename(strdup(argv[2]));
size_t FWnameLen = strlen(FWname);
myassert(FWnameLen <= 255, 0x0f, "Firmware filename '%s' is too long\n", FWname);
uint8_t n8 = FWnameLen;
// Open and check firmware file
FILE *FW = fopen(argv[2], "r");
myassert(FW, 0x10, "Failed to open '%s' for reading\n", argv[2]);
char buf[0x20];
myassert(1 == fread(buf, 7, 1, FW), 0x10, "Failed to read from '%s'\n", argv[2]);
myassert(!memcmp(buf, BFL_FILE_MAGIC, sizeof(BFL_FILE_MAGIC)-1), 0x11, "'%s' doesn't look like a BFL firmware\n", argv[2]);
myassert(!fseek(FW, 0, SEEK_END), 0x12, "Failed to find end of '%s'\n", argv[2]);
long FWlen = ftell(FW);
myassert(FWlen > 0, 0x12, "Couldn't get size of '%s'\n", argv[2]);
myassert(!fseek(FW, 7, SEEK_SET), 0x12, "Failed to rewind firmware file after getting size\n");
FWlen -= 7;
printf("Firmware file looks OK :)\n");
// Open device
FILE *BFL = fopen(argv[1], "r+");
myassert(BFL, 0x20, "Failed to open '%s' for read/write\n", argv[1]);
myassert(!setvbuf(BFL, NULL, _IOFBF, 1032), 0x21, "Failed to setup buffer for device");
// ZAX: Start firmware upload
printf("Starting firmware upload... ");
myassert(1 == fwrite("ZAX", 3, 1, BFL), 0x22, "Failed to issue ZAX command\n");
WAITFOROK(0x22, "ZAX");
// Firmware upload header
myassert(1 == fwrite(BFL_UPLOAD_MAGIC, sizeof(BFL_UPLOAD_MAGIC)-1, 1, BFL), 0x23, "Failed to send firmware upload header (magic)\n");
uint32_t n32 = htonl(FWlen - FWlen / 6);
myassert(1 == fwrite(&n32, sizeof(n32), 1, BFL), 0x23, "Failed to send firmware upload header (size)\n");
myassert(1 == fwrite("\0\0", 2 , 1, BFL), 0x23, "Failed to send firmware upload header (padding 1)\n");
myassert(1 == fwrite(&n8, sizeof(n8) , 1, BFL), 0x23, "Failed to send firmware upload header (filename length)\n");
myassert(1 == fwrite(FWname, n8 , 1, BFL), 0x23, "Failed to send firmware upload header (filename)\n");
myassert(1 == fwrite("\0>>>>>>>>", 9 , 1, BFL), 0x23, "Failed to send firmware upload header (padding 2)\n");
WAITFOROK(0x23, "firmware upload header");
printf("OK, sending...\n");
// Actual firmware upload
long i, j;
for (i = 0, j = 0; i < FWlen; ++i) {
myassert(1 == fread(&n8, sizeof(n8), 1, FW), 0x30, "Error reading data from firmware file\n");
if (5 == i % 6)
continue;
n8 ^= 0x2f;
myassert(1 == fwrite(&n8, sizeof(n8), 1, BFL), 0x31, "Error sending data to device\n");
if (!(++j % 0x400)) {
myassert(1 == fwrite(">>>>>>>>", 8, 1, BFL), 0x32, "Error sending block-finish to device\n");
printf("\r%5.2f%% complete", (double)i * 100. / (double)FWlen);
WAITFOROK(0x32, "block-finish");
}
}
printf("\r100%% complete :)\n");
myassert(1 == fwrite(">>>>>>>>", 8, 1, BFL), 0x3f, "Error sending upload-finished to device\n");
myassert(fgets(buf, sizeof(buf), BFL), 0x3f, "Error reading response from upload-finished\n");
myassert(!strcmp(buf, "DONE\n"), 0x3f, "Invalid response from upload-finished: %s%s", ERRRESP(buf));
// ZBX: Finish programming
printf("Waiting for device... ");
myassert(1 == fwrite("ZBX", 3, 1, BFL), 0x40, "Failed to issue ZBX command\n");
WAITFOROK(0x40, "ZBX");
printf("All done! Try mining to test the flash succeeded.\n");
return 0;
}

242
cgminer.c

@ -85,16 +85,13 @@ static char packagename[255];
bool opt_protocol; bool opt_protocol;
static bool opt_benchmark; static bool opt_benchmark;
static bool have_longpoll; bool have_longpoll;
static bool want_per_device_stats; static bool want_per_device_stats;
bool use_syslog; bool use_syslog;
bool opt_quiet; bool opt_quiet;
static bool opt_realquiet; static bool opt_realquiet;
bool opt_loginput; bool opt_loginput;
const int opt_cutofftemp = 95; const int opt_cutofftemp = 95;
static int opt_retries = -1;
static int opt_fail_pause = 5;
static int fail_pause = 5;
int opt_log_interval = 5; int opt_log_interval = 5;
static int opt_queue = 1; static int opt_queue = 1;
int opt_scantime = 60; int opt_scantime = 60;
@ -170,7 +167,7 @@ static pthread_mutex_t hash_lock;
static pthread_mutex_t qd_lock; static pthread_mutex_t qd_lock;
static pthread_mutex_t *stgd_lock; static pthread_mutex_t *stgd_lock;
pthread_mutex_t console_lock; pthread_mutex_t console_lock;
static pthread_mutex_t ch_lock; pthread_mutex_t ch_lock;
static pthread_rwlock_t blk_lock; static pthread_rwlock_t blk_lock;
pthread_rwlock_t netacc_lock; pthread_rwlock_t netacc_lock;
@ -213,8 +210,10 @@ bool curses_active;
static char current_block[37]; static char current_block[37];
static char *current_hash; static char *current_hash;
char *current_fullhash;
static char datestamp[40]; static char datestamp[40];
static char blocktime[30]; static char blocktime[30];
struct timeval block_timeval;
struct block { struct block {
char hash[37]; char hash[37];
@ -732,6 +731,11 @@ static char *set_icarus_timing(const char *arg)
} }
#endif #endif
static char *set_null(const char __maybe_unused *arg)
{
return NULL;
}
/* These options are available from config file or commandline */ /* These options are available from config file or commandline */
static struct opt_table opt_config_table[] = { static struct opt_table opt_config_table[] = {
#ifdef WANT_CPUMINE #ifdef WANT_CPUMINE
@ -954,12 +958,12 @@ static struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--remove-disabled", OPT_WITHOUT_ARG("--remove-disabled",
opt_set_bool, &opt_removedisabled, opt_set_bool, &opt_removedisabled,
"Remove disabled devices entirely, as if they didn't exist"), "Remove disabled devices entirely, as if they didn't exist"),
OPT_WITH_ARG("--retries|-r", OPT_WITH_ARG("--retries",
opt_set_intval, opt_show_intval, &opt_retries, set_null, NULL, NULL,
"Number of times to retry before giving up, if JSON-RPC call fails (-1 means never)"), opt_hidden),
OPT_WITH_ARG("--retry-pause|-R", OPT_WITH_ARG("--retry-pause",
set_int_0_to_9999, opt_show_intval, &opt_fail_pause, set_null, NULL, NULL,
"Number of seconds to pause, between retries"), opt_hidden),
OPT_WITH_ARG("--rotate", OPT_WITH_ARG("--rotate",
set_rotate, opt_show_intval, &opt_rotate_period, set_rotate, opt_show_intval, &opt_rotate_period,
"Change multipool strategy from failover to regularly rotate at N minutes"), "Change multipool strategy from failover to regularly rotate at N minutes"),
@ -1739,7 +1743,7 @@ static void reject_pool(struct pool *pool)
pool->enabled = POOL_REJECTING; pool->enabled = POOL_REJECTING;
} }
static bool submit_upstream_work(const struct work *work, CURL *curl) static bool submit_upstream_work(const struct work *work, CURL *curl, bool resubmit)
{ {
char *hexstr = NULL; char *hexstr = NULL;
json_t *val, *res; json_t *val, *res;
@ -1814,11 +1818,11 @@ static bool submit_upstream_work(const struct work *work, CURL *curl)
applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)"); applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)");
if (!QUIET) { if (!QUIET) {
if (total_pools > 1) if (total_pools > 1)
applog(LOG_NOTICE, "Accepted %s %s %d pool %d", applog(LOG_NOTICE, "Accepted %s %s %d pool %d %s",
hashshow, cgpu->api->name, cgpu->device_id, work->pool->pool_no); hashshow, cgpu->api->name, cgpu->device_id, work->pool->pool_no, resubmit ? "(resubmit)" : "");
else else
applog(LOG_NOTICE, "Accepted %s %s %d", applog(LOG_NOTICE, "Accepted %s %s %d %s",
hashshow, cgpu->api->name, cgpu->device_id); hashshow, cgpu->api->name, cgpu->device_id, resubmit ? "(resubmit)" : "");
} }
sharelog("accept", work); sharelog("accept", work);
if (opt_shares && total_accepted >= opt_shares) { if (opt_shares && total_accepted >= opt_shares) {
@ -1867,8 +1871,8 @@ static bool submit_upstream_work(const struct work *work, CURL *curl)
} else } else
strcpy(reason, ""); strcpy(reason, "");
applog(LOG_NOTICE, "Rejected %s %s %d %s%s", applog(LOG_NOTICE, "Rejected %s %s %d %s%s %s",
hashshow, cgpu->api->name, cgpu->device_id, where, reason); hashshow, cgpu->api->name, cgpu->device_id, where, reason, resubmit ? "(resubmit)" : "");
sharelog(disposition, work); sharelog(disposition, work);
} }
@ -1951,9 +1955,11 @@ static inline struct pool *select_pool(bool lagging)
if (pool_strategy == POOL_BALANCE) if (pool_strategy == POOL_BALANCE)
return select_balanced(cp); return select_balanced(cp);
if (pool_strategy != POOL_LOADBALANCE && (!lagging || opt_fail_only)) if (pool_strategy != POOL_LOADBALANCE && (!lagging || opt_fail_only)) {
pool = cp; if (cp->prio != 0)
else switch_pools(NULL);
pool = current_pool();
} else
pool = NULL; pool = NULL;
while (!pool) { while (!pool) {
@ -1989,7 +1995,6 @@ static bool get_upstream_work(struct work *work, CURL *curl)
struct timeval tv_start, tv_end, tv_elapsed; struct timeval tv_start, tv_end, tv_elapsed;
json_t *val = NULL; json_t *val = NULL;
bool rc = false; bool rc = false;
int retries = 0;
char *url; char *url;
applog(LOG_DEBUG, "DBG: sending %s get RPC call: %s", pool->rpc_url, rpc_req); applog(LOG_DEBUG, "DBG: sending %s get RPC call: %s", pool->rpc_url, rpc_req);
@ -1997,23 +2002,17 @@ static bool get_upstream_work(struct work *work, CURL *curl)
url = pool->rpc_url; url = pool->rpc_url;
gettimeofday(&tv_start, NULL); gettimeofday(&tv_start, NULL);
retry:
/* A single failure response here might be reported as a dead pool and val = json_rpc_call(curl, url, pool->rpc_userpass, rpc_req, false,
* there may be temporary denied messages etc. falsely reporting false, &work->rolltime, pool, false);
* failure so retry a few times before giving up */
while (!val && retries++ < 3) {
pool_stats->getwork_attempts++; pool_stats->getwork_attempts++;
val = json_rpc_call(curl, url, pool->rpc_userpass, rpc_req,
false, false, &work->rolltime, pool, false);
}
if (unlikely(!val)) {
applog(LOG_DEBUG, "Failed json_rpc_call in get_upstream_work");
goto out;
}
if (likely(val)) {
rc = work_decode(json_object_get(val, "result"), work); rc = work_decode(json_object_get(val, "result"), work);
if (!rc && retries < 3) if (unlikely(!rc))
goto retry; applog(LOG_DEBUG, "Failed to decode work in get_upstream_work");
} else
applog(LOG_DEBUG, "Failed json_rpc_call in get_upstream_work");
gettimeofday(&tv_end, NULL); gettimeofday(&tv_end, NULL);
timersub(&tv_end, &tv_start, &tv_elapsed); timersub(&tv_end, &tv_start, &tv_elapsed);
@ -2036,8 +2035,8 @@ retry:
total_getworks++; total_getworks++;
pool->getwork_requested++; pool->getwork_requested++;
if (likely(val))
json_decref(val); json_decref(val);
out:
return rc; return rc;
} }
@ -2048,7 +2047,9 @@ static struct work *make_work(void)
if (unlikely(!work)) if (unlikely(!work))
quit(1, "Failed to calloc work in make_work"); quit(1, "Failed to calloc work in make_work");
mutex_lock(&control_lock);
work->id = total_work++; work->id = total_work++;
mutex_unlock(&control_lock);
return work; return work;
} }
@ -2218,7 +2219,7 @@ static void recruit_curl(struct pool *pool)
* network delays/outages. */ * network delays/outages. */
static struct curl_ent *pop_curl_entry(struct pool *pool) static struct curl_ent *pop_curl_entry(struct pool *pool)
{ {
int curl_limit = opt_delaynet ? 5 : mining_threads * 4 / 3; int curl_limit = opt_delaynet ? 5 : (mining_threads + opt_queue) * 2;
struct curl_ent *ce; struct curl_ent *ce;
mutex_lock(&pool->pool_lock); mutex_lock(&pool->pool_lock);
@ -2226,7 +2227,7 @@ retry:
if (!pool->curls) if (!pool->curls)
recruit_curl(pool); recruit_curl(pool);
else if (list_empty(&pool->curlring)) { else if (list_empty(&pool->curlring)) {
if (pool->submit_fail || pool->curls >= curl_limit) { if (pool->curls >= curl_limit) {
pthread_cond_wait(&pool->cr_cond, &pool->pool_lock); pthread_cond_wait(&pool->cr_cond, &pool->pool_lock);
goto retry; goto retry;
} else } else
@ -2384,21 +2385,22 @@ static void *get_work_thread(void *userdata)
struct workio_cmd *wc = (struct workio_cmd *)userdata; struct workio_cmd *wc = (struct workio_cmd *)userdata;
int ts, tq, maxq = opt_queue + mining_threads; int ts, tq, maxq = opt_queue + mining_threads;
struct pool *pool = current_pool(); struct pool *pool = current_pool();
struct work *ret_work= NULL;
struct curl_ent *ce = NULL; struct curl_ent *ce = NULL;
struct work *ret_work; bool lagging = false;
int failures = 0;
pthread_detach(pthread_self()); pthread_detach(pthread_self());
applog(LOG_DEBUG, "Creating extra get work thread"); applog(LOG_DEBUG, "Creating extra get work thread");
retry:
tq = global_queued(); tq = global_queued();
ts = total_staged(); ts = total_staged();
if (ts >= maxq) if (ts >= maxq)
goto out; goto out;
if (ts >= opt_queue && tq >= maxq - 1) if (ts >= opt_queue && tq >= maxq)
goto out; goto out;
if (clone_available()) if (clone_available())
@ -2410,34 +2412,37 @@ static void *get_work_thread(void *userdata)
else else
ret_work->thr = NULL; ret_work->thr = NULL;
if (opt_benchmark) if (opt_benchmark) {
get_benchmark_work(ret_work); get_benchmark_work(ret_work);
else { ret_work->queued = true;
bool lagging = false; } else {
if (ts <= opt_queue) if (!ts)
lagging = true; lagging = true;
pool = ret_work->pool = select_pool(lagging); pool = ret_work->pool = select_pool(lagging);
inc_queued(); inc_queued();
if (!ce)
ce = pop_curl_entry(pool); ce = pop_curl_entry(pool);
/* obtain new work from bitcoin via JSON-RPC */ /* Check that we haven't staged work via other threads while
while (!get_upstream_work(ret_work, ce->curl)) { * waiting for a curl entry */
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { if (total_staged() >= maxq) {
applog(LOG_ERR, "json_rpc_call failed, terminating workio thread"); dec_queued();
free_work(ret_work); free_work(ret_work);
kill_work();
goto out; goto out;
} }
/* obtain new work from bitcoin via JSON-RPC */
if (!get_upstream_work(ret_work, ce->curl)) {
/* pause, then restart work-request loop */ /* pause, then restart work-request loop */
applog(LOG_DEBUG, "json_rpc_call failed on get work, retry after %d seconds", applog(LOG_DEBUG, "json_rpc_call failed on get work, retrying");
fail_pause); lagging = true;
sleep(fail_pause); dec_queued();
fail_pause += opt_fail_pause; free_work(ret_work);
goto retry;
} }
fail_pause = opt_fail_pause;
ret_work->queued = true; ret_work->queued = true;
} }
@ -2534,8 +2539,8 @@ static void *submit_work_thread(void *userdata)
struct workio_cmd *wc = (struct workio_cmd *)userdata; struct workio_cmd *wc = (struct workio_cmd *)userdata;
struct work *work = wc->work; struct work *work = wc->work;
struct pool *pool = work->pool; struct pool *pool = work->pool;
bool resubmit = false;
struct curl_ent *ce; struct curl_ent *ce;
int failures = 0;
pthread_detach(pthread_self()); pthread_detach(pthread_self());
@ -2560,26 +2565,18 @@ static void *submit_work_thread(void *userdata)
ce = pop_curl_entry(pool); ce = pop_curl_entry(pool);
/* submit solution to bitcoin via JSON-RPC */ /* submit solution to bitcoin via JSON-RPC */
while (!submit_upstream_work(work, ce->curl)) { while (!submit_upstream_work(work, ce->curl, resubmit)) {
resubmit = true;
if (stale_work(work, true)) { if (stale_work(work, true)) {
applog(LOG_NOTICE, "Share became stale while retrying submit, discarding"); applog(LOG_NOTICE, "Share became stale while retrying submit, discarding");
total_stale++; total_stale++;
pool->stale_shares++; pool->stale_shares++;
break; break;
} }
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) {
applog(LOG_ERR, "Failed %d retries ...terminating workio thread", opt_retries);
kill_work();
break;
}
/* pause, then restart work-request loop */ /* pause, then restart work-request loop */
applog(LOG_INFO, "json_rpc_call failed on submit_work, retry after %d seconds", applog(LOG_INFO, "json_rpc_call failed on submit_work, retrying");
fail_pause);
sleep(fail_pause);
fail_pause += opt_fail_pause;
} }
fail_pause = opt_fail_pause;
push_curl_entry(ce, pool); push_curl_entry(ce, pool);
out: out:
workio_cmd_free(wc); workio_cmd_free(wc);
@ -2785,22 +2782,27 @@ static void restart_threads(void)
static void set_curblock(char *hexstr, unsigned char *hash) static void set_curblock(char *hexstr, unsigned char *hash)
{ {
unsigned char hash_swap[32]; unsigned char hash_swap[32];
struct timeval tv_now; unsigned char block_hash_swap[32];
char *old_hash; char *old_hash;
strcpy(current_block, hexstr); strcpy(current_block, hexstr);
gettimeofday(&tv_now, NULL);
get_timestamp(blocktime, &tv_now);
swap256(hash_swap, hash); swap256(hash_swap, hash);
swap256(block_hash_swap, hash+4);
/* Don't free current_hash directly to avoid dereferencing when read /* Don't free current_hash directly to avoid dereferencing when read
* elsewhere */ * elsewhere - and update block_timeval inside the same lock */
mutex_lock(&ch_lock); mutex_lock(&ch_lock);
gettimeofday(&block_timeval, NULL);
old_hash = current_hash; old_hash = current_hash;
current_hash = bin2hex(hash_swap, 16); current_hash = bin2hex(hash_swap, 16);
free(old_hash); free(old_hash);
old_hash = current_fullhash;
current_fullhash = bin2hex(block_hash_swap, 32);
free(old_hash);
mutex_unlock(&ch_lock); mutex_unlock(&ch_lock);
get_timestamp(blocktime, &block_timeval);
if (unlikely(!current_hash)) if (unlikely(!current_hash))
quit (1, "set_curblock OOM"); quit (1, "set_curblock OOM");
applog(LOG_INFO, "New block: %s...", current_hash); applog(LOG_INFO, "New block: %s...", current_hash);
@ -2856,6 +2858,20 @@ static void test_work_current(struct work *work)
quit (1, "test_work_current OOM"); quit (1, "test_work_current OOM");
strcpy(s->hash, hexstr); strcpy(s->hash, hexstr);
wr_lock(&blk_lock); wr_lock(&blk_lock);
/* Only keep the last 6 blocks in memory since work from blocks
* before this is virtually impossible and we want to prevent
* memory usage from continually rising */
if (HASH_COUNT(blocks) > 5) {
struct block *blocka, *blockb;
int count = 0;
HASH_ITER(hh, blocks, blocka, blockb) {
if (count++ < 6)
continue;
HASH_DEL(blocks, blocka);
free(blocka);
}
}
HASH_ADD_STR(blocks, hash, s); HASH_ADD_STR(blocks, hash, s);
wr_unlock(&blk_lock); wr_unlock(&blk_lock);
set_curblock(hexstr, work->data); set_curblock(hexstr, work->data);
@ -2898,12 +2914,7 @@ static bool work_rollable(struct work *work)
static bool hash_push(struct work *work) static bool hash_push(struct work *work)
{ {
bool rc = true, dec = false; bool rc = true;
if (work->queued) {
work->queued = false;
dec = true;
}
mutex_lock(stgd_lock); mutex_lock(stgd_lock);
if (work_rollable(work)) if (work_rollable(work))
@ -2916,8 +2927,10 @@ static bool hash_push(struct work *work)
pthread_cond_signal(&getq->cond); pthread_cond_signal(&getq->cond);
mutex_unlock(stgd_lock); mutex_unlock(stgd_lock);
if (dec) if (work->queued) {
work->queued = false;
dec_queued(); dec_queued();
}
return rc; return rc;
} }
@ -3507,9 +3520,9 @@ static void set_options(void)
immedok(logwin, true); immedok(logwin, true);
clear_logwin(); clear_logwin();
retry: retry:
wlogprint("[Q]ueue: %d\n[S]cantime: %d\n[E]xpiry: %d\n[R]etries: %d\n" wlogprint("[Q]ueue: %d\n[S]cantime: %d\n[E]xpiry: %d\n"
"[P]ause: %d\n[W]rite config file\n[C]gminer restart\n", "[W]rite config file\n[C]gminer restart\n",
opt_queue, opt_scantime, opt_expiry, opt_retries, opt_fail_pause); opt_queue, opt_scantime, opt_expiry);
wlogprint("Select an option or any other key to return\n"); wlogprint("Select an option or any other key to return\n");
input = getch(); input = getch();
@ -3537,22 +3550,6 @@ retry:
} }
opt_expiry = selected; opt_expiry = selected;
goto retry; goto retry;
} else if (!strncasecmp(&input, "r", 1)) {
selected = curses_int("Retries before failing (-1 infinite)");
if (selected < -1 || selected > 9999) {
wlogprint("Invalid selection\n");
goto retry;
}
opt_retries = selected;
goto retry;
} else if (!strncasecmp(&input, "p", 1)) {
selected = curses_int("Seconds to pause before network retries");
if (selected < 1 || selected > 9999) {
wlogprint("Invalid selection\n");
goto retry;
}
opt_fail_pause = selected;
goto retry;
} else if (!strncasecmp(&input, "w", 1)) { } else if (!strncasecmp(&input, "w", 1)) {
FILE *fcfg; FILE *fcfg;
char *str, filename[PATH_MAX], prompt[PATH_MAX + 50]; char *str, filename[PATH_MAX], prompt[PATH_MAX + 50];
@ -4027,14 +4024,12 @@ static struct work *clone_work(struct work *work)
return work; return work;
} }
static bool get_work(struct work *work, struct thr_info *thr, const int thr_id) static void get_work(struct work *work, struct thr_info *thr, const int thr_id)
{ {
struct timespec abstime = {0, 0}; struct timespec abstime = {0, 0};
struct work *work_heap; struct work *work_heap;
struct timeval now; struct timeval now;
struct pool *pool; struct pool *pool;
int failures = 0;
bool ret = false;
/* Tell the watchdog thread this thread is waiting on getwork and /* Tell the watchdog thread this thread is waiting on getwork and
* should not be restarted */ * should not be restarted */
@ -4042,17 +4037,14 @@ static bool get_work(struct work *work, struct thr_info *thr, const int thr_id)
if (opt_benchmark) { if (opt_benchmark) {
get_benchmark_work(work); get_benchmark_work(work);
thread_reportin(thr); goto out;
return true;
} }
retry: retry:
pool = current_pool(); pool = current_pool();
if (reuse_work(work)) { if (reuse_work(work))
ret = true;
goto out; goto out;
}
if (!pool->lagging && !total_staged() && global_queued() >= mining_threads + opt_queue) { if (!pool->lagging && !total_staged() && global_queued() >= mining_threads + opt_queue) {
struct cgpu_info *cgpu = thr->cgpu; struct cgpu_info *cgpu = thr->cgpu;
@ -4102,29 +4094,13 @@ retry:
pool_resus(pool); pool_resus(pool);
} }
work_heap = clone_work(work_heap);
memcpy(work, work_heap, sizeof(struct work)); memcpy(work, work_heap, sizeof(struct work));
free_work(work_heap); free_work(work_heap);
ret = true;
out: out:
if (unlikely(ret == false)) {
if ((opt_retries >= 0) && (++failures > opt_retries)) {
applog(LOG_ERR, "Failed %d times to get_work");
return ret;
}
applog(LOG_DEBUG, "Retrying after %d seconds", fail_pause);
sleep(fail_pause);
fail_pause += opt_fail_pause;
goto retry;
}
fail_pause = opt_fail_pause;
work->thr_id = thr_id; work->thr_id = thr_id;
thread_reportin(thr); thread_reportin(thr);
if (ret)
work->mined = true; work->mined = true;
return ret;
} }
bool submit_work_sync(struct thr_info *thr, const struct work *work_in) bool submit_work_sync(struct thr_info *thr, const struct work *work_in)
@ -4281,11 +4257,9 @@ void *miner_thread(void *userdata)
mythr->work_restart = false; mythr->work_restart = false;
if (api->free_work && likely(work->pool)) if (api->free_work && likely(work->pool))
api->free_work(mythr, work); api->free_work(mythr, work);
if (unlikely(!get_work(work, mythr, thr_id))) { get_work(work, mythr, thr_id);
applog(LOG_ERR, "work retrieval failed, exiting " cgpu->new_work = true;
"mining thread %d", thr_id);
break;
}
gettimeofday(&tv_workstart, NULL); gettimeofday(&tv_workstart, NULL);
work->blk.nonce = 0; work->blk.nonce = 0;
cgpu->max_hashes = 0; cgpu->max_hashes = 0;
@ -4570,16 +4544,9 @@ retry_pool:
gettimeofday(&end, NULL); gettimeofday(&end, NULL);
if (end.tv_sec - start.tv_sec > 30) if (end.tv_sec - start.tv_sec > 30)
continue; continue;
if (opt_retries == -1 || failures++ < opt_retries) {
if (failures == 1) if (failures == 1)
applog(LOG_WARNING, applog(LOG_WARNING, "longpoll failed for %s, retrying every 30s", pool->lp_url);
"longpoll failed for %s, retrying every 30s", pool->lp_url);
sleep(30); sleep(30);
} else {
applog(LOG_ERR,
"longpoll failed for %s, ending thread", pool->lp_url);
goto out;
}
} }
if (pool != cp) { if (pool != cp) {
pool = select_longpoll_pool(cp); pool = select_longpoll_pool(cp);
@ -4618,7 +4585,7 @@ static void reap_curl(struct pool *pool)
list_for_each_entry_safe(ent, iter, &pool->curlring, node) { list_for_each_entry_safe(ent, iter, &pool->curlring, node) {
if (pool->curls < 2) if (pool->curls < 2)
break; break;
if (now.tv_sec - ent->tv.tv_sec > 60) { if (now.tv_sec - ent->tv.tv_sec > 300) {
reaped++; reaped++;
pool->curls--; pool->curls--;
list_del(&ent->node); list_del(&ent->node);
@ -5754,6 +5721,9 @@ begin_bench:
pthread_detach(thr->pth); pthread_detach(thr->pth);
#endif #endif
for (i = 0; i < mining_threads + opt_queue; i++)
queue_request(NULL, false);
/* main loop - simply wait for workio thread to exit. This is not the /* main loop - simply wait for workio thread to exit. This is not the
* normal exit path and only occurs should the workio_thread die * normal exit path and only occurs should the workio_thread die
* unexpectedly */ * unexpectedly */

12
configure.ac

@ -2,7 +2,7 @@
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_maj], [2]) m4_define([v_maj], [2])
m4_define([v_min], [7]) m4_define([v_min], [7])
m4_define([v_mic], [0]) m4_define([v_mic], [2])
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_ver], [v_maj.v_min.v_mic]) m4_define([v_ver], [v_maj.v_min.v_mic])
m4_define([lt_rev], m4_eval(v_maj + v_min)) m4_define([lt_rev], m4_eval(v_maj + v_min))
@ -389,11 +389,11 @@ fi
AC_DEFINE_UNQUOTED([CGMINER_PREFIX], ["$prefix/bin"], [Path to cgminer install]) AC_DEFINE_UNQUOTED([CGMINER_PREFIX], ["$prefix/bin"], [Path to cgminer install])
AC_DEFINE_UNQUOTED([PHATK_KERNNAME], ["phatk120724"], [Filename for phatk kernel]) AC_DEFINE_UNQUOTED([PHATK_KERNNAME], ["phatk120823"], [Filename for phatk kernel])
AC_DEFINE_UNQUOTED([POCLBM_KERNNAME], ["poclbm120724"], [Filename for poclbm kernel]) AC_DEFINE_UNQUOTED([POCLBM_KERNNAME], ["poclbm120823"], [Filename for poclbm kernel])
AC_DEFINE_UNQUOTED([DIAKGCN_KERNNAME], ["diakgcn120724"], [Filename for diakgcn kernel]) AC_DEFINE_UNQUOTED([DIAKGCN_KERNNAME], ["diakgcn120823"], [Filename for diakgcn kernel])
AC_DEFINE_UNQUOTED([DIABLO_KERNNAME], ["diablo120724"], [Filename for diablo kernel]) AC_DEFINE_UNQUOTED([DIABLO_KERNNAME], ["diablo120823"], [Filename for diablo kernel])
AC_DEFINE_UNQUOTED([SCRYPT_KERNNAME], ["scrypt120724"], [Filename for scrypt kernel]) AC_DEFINE_UNQUOTED([SCRYPT_KERNNAME], ["scrypt120823"], [Filename for scrypt kernel])
AC_SUBST(OPENCL_LIBS) AC_SUBST(OPENCL_LIBS)

51
diablo120724.cl → diablo120823.cl

@ -62,7 +62,7 @@ void search(
const uint c1_plus_k5, const uint b1_plus_k6, const uint c1_plus_k5, const uint b1_plus_k6,
const uint state0, const uint state1, const uint state2, const uint state3, const uint state0, const uint state1, const uint state2, const uint state3,
const uint state4, const uint state5, const uint state6, const uint state7, const uint state4, const uint state5, const uint state6, const uint state7,
__global uint * output) volatile __global uint * output)
{ {
z ZA[930]; z ZA[930];
@ -1242,33 +1242,50 @@ void search(
ZA[924] = (ZCh(ZA[922], ZA[920], ZA[918]) + ZA[923]) + ZR26(ZA[922]); ZA[924] = (ZCh(ZA[922], ZA[920], ZA[918]) + ZA[923]) + ZR26(ZA[922]);
#define FOUND (0x800) #define FOUND (0x0F)
#define NFLAG (0x7FF)
#if defined(VECTORS4) #if defined(VECTORS4)
bool result = any(ZA[924] == 0x136032EDU); bool result = any(ZA[924] == 0x136032EDU);
if (result) { if (result) {
if (ZA[924].x == 0x136032EDU) uint found;
output[FOUND] = output[NFLAG & Znonce.x] = Znonce.x;
if (ZA[924].y == 0x136032EDU) if (ZA[924].x == 0x136032EDU) {
output[FOUND] = output[NFLAG & Znonce.y] = Znonce.y; found = atomic_add(&output[FOUND], 1);
if (ZA[924].z == 0x136032EDU) output[found] = Znonce.x;
output[FOUND] = output[NFLAG & Znonce.z] = Znonce.z; }
if (ZA[924].w == 0x136032EDU) if (ZA[924].y == 0x136032EDU) {
output[FOUND] = output[NFLAG & Znonce.w] = Znonce.w; found = atomic_add(&output[FOUND], 1);
output[found] = Znonce.y;
}
if (ZA[924].z == 0x136032EDU) {
found = atomic_add(&output[FOUND], 1);
output[found] = Znonce.z;
}
if (ZA[924].w == 0x136032EDU) {
found = atomic_add(&output[FOUND], 1);
output[found] = Znonce.w;
}
} }
#elif defined(VECTORS2) #elif defined(VECTORS2)
bool result = any(ZA[924] == 0x136032EDU); bool result = any(ZA[924] == 0x136032EDU);
if (result) { if (result) {
if (ZA[924].x == 0x136032EDU) uint found;
output[FOUND] = output[NFLAG & Znonce.x] = Znonce.x;
if (ZA[924].y == 0x136032EDU) if (ZA[924].x == 0x136032EDU) {
output[FOUND] = output[NFLAG & Znonce.y] = Znonce.y; found = atomic_add(&output[FOUND], 1);
output[found] = Znonce.x;
}
if (ZA[924].y == 0x136032EDU) {
found = atomic_add(&output[FOUND], 1);
output[found] = Znonce.y;
}
} }
#else #else
if (ZA[924] == 0x136032EDU) if (ZA[924] == 0x136032EDU) {
output[FOUND] = output[NFLAG & Znonce] = Znonce; uint found = atomic_add(&output[FOUND], 1);
output[found] = Znonce;
}
#endif #endif
} }

47
diakgcn120724.cl → diakgcn120823.cl

@ -48,7 +48,7 @@ __kernel
const uint state0A, const uint state0B, const uint state0A, const uint state0B,
const uint state1A, const uint state2A, const uint state3A, const uint state4A, const uint state1A, const uint state2A, const uint state3A, const uint state4A,
const uint state5A, const uint state6A, const uint state7A, const uint state5A, const uint state6A, const uint state7A,
__global uint * output) volatile __global uint * output)
{ {
u V[8]; u V[8];
u W[16]; u W[16];
@ -571,17 +571,46 @@ __kernel
V[7] += V[3] + W[12] + ch(V[0], V[1], V[2]) + rotr26(V[0]); V[7] += V[3] + W[12] + ch(V[0], V[1], V[2]) + rotr26(V[0]);
#define FOUND (0x800) #define FOUND (0x0F)
#define NFLAG (0x7FF)
#ifdef VECTORS4 #ifdef VECTORS4
if ((V[7].x == 0x136032edU) ^ (V[7].y == 0x136032edU) ^ (V[7].z == 0x136032edU) ^ (V[7].w == 0x136032edU)) if ((V[7].x == 0x136032edU) ^ (V[7].y == 0x136032edU) ^ (V[7].z == 0x136032edU) ^ (V[7].w == 0x136032edU)) {
output[FOUND] = output[NFLAG & nonce.x] = (V[7].x == 0x136032edU) ? nonce.x : ((V[7].y == 0x136032edU) ? nonce.y : ((V[7].z == 0x136032edU) ? nonce.z : nonce.w)); uint found;
if (V[7].x == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.x;
}
if (V[7].y == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.y;
}
if (V[7].z == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.z;
}
if (V[7].w == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.w;
}
}
#elif defined VECTORS2 #elif defined VECTORS2
if ((V[7].x == 0x136032edU) + (V[7].y == 0x136032edU)) if ((V[7].x == 0x136032edU) + (V[7].y == 0x136032edU)) {
output[FOUND] = output[NFLAG & nonce.x] = (V[7].x == 0x136032edU) ? nonce.x : nonce.y; uint found;
if (V[7].x == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.x;
}
if (V[7].y == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.y;
}
}
#else #else
if (V[7] == 0x136032edU) if (V[7] == 0x136032edU) {
output[FOUND] = output[NFLAG & nonce] = nonce; uint found = atomic_add(&output[FOUND], 1);
output[found] = nonce;
}
#endif #endif
} }

2
driver-bitforce.c

@ -175,7 +175,7 @@ static int bitforce_autodetect_ftdi(void)
applog(LOG_DEBUG, "FTDI reports %u devices", (unsigned)numDevs); applog(LOG_DEBUG, "FTDI reports %u devices", (unsigned)numDevs);
buf = alloca(65 * numDevs); buf = alloca(65 * numDevs);
bufptrs = alloca(numDevs + 1); bufptrs = alloca(sizeof(*bufptrs) * (numDevs + 1));
for (i = 0; i < numDevs; ++i) for (i = 0; i < numDevs; ++i)
bufptrs[i] = &buf[i * 65]; bufptrs[i] = &buf[i * 65];

93
driver-opencl.c

@ -1460,6 +1460,10 @@ static void opencl_free_work(struct thr_info *thr, struct work *work)
const int thr_id = thr->id; const int thr_id = thr->id;
struct opencl_thread_data *thrdata = thr->cgpu_data; struct opencl_thread_data *thrdata = thr->cgpu_data;
_clState *clState = clStates[thr_id]; _clState *clState = clStates[thr_id];
struct cgpu_info *gpu = thr->cgpu;
if (gpu->dynamic)
return;
clFinish(clState->commandQueue); clFinish(clState->commandQueue);
if (thrdata->res[FOUND]) { if (thrdata->res[FOUND]) {
@ -1491,7 +1495,6 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
const cl_kernel *kernel = &clState->kernel; const cl_kernel *kernel = &clState->kernel;
const int dynamic_us = opt_dynamic_interval * 1000; const int dynamic_us = opt_dynamic_interval * 1000;
struct timeval tv_gpuend; struct timeval tv_gpuend;
cl_bool blocking;
cl_int status; cl_int status;
size_t globalThreads[1]; size_t globalThreads[1];
@ -1499,57 +1502,19 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
unsigned int threads; unsigned int threads;
int64_t hashes; int64_t hashes;
if (gpu->dynamic)
blocking = CL_TRUE;
else
blocking = CL_FALSE;
/* This finish flushes the readbuffer set with CL_FALSE later */ /* This finish flushes the readbuffer set with CL_FALSE later */
if (!blocking) if (!gpu->dynamic)
clFinish(clState->commandQueue); clFinish(clState->commandQueue);
if (gpu->dynamic) {
double gpu_us;
/* Windows returns the same time for gettimeofday due to its
* 15ms timer resolution, so we must average the result over
* at least 5 values that are actually different to get an
* accurate result */
gpu->intervals++;
gettimeofday(&tv_gpuend, NULL);
gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpumid);
if (gpu_us > 0 && ++gpu->hit > 4) {
gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpustart) / gpu->intervals;
gpu->gpu_us_average = (gpu->gpu_us_average + gpu_us * 0.63) / 1.63;
/* Try to not let the GPU be out for longer than
* opt_dynamic_interval in ms, but increase
* intensity when the system is idle in dynamic mode */
if (gpu->gpu_us_average > dynamic_us) {
if (gpu->intensity > MIN_INTENSITY)
--gpu->intensity;
} else if (gpu->gpu_us_average < dynamic_us / 2) {
if (gpu->intensity < MAX_INTENSITY)
++gpu->intensity;
}
gpu->intervals = gpu->hit = 0;
}
}
set_threads_hashes(clState->vwidth, &threads, &hashes, globalThreads, set_threads_hashes(clState->vwidth, &threads, &hashes, globalThreads,
localThreads[0], gpu->intensity); localThreads[0], gpu->intensity);
if (hashes > gpu->max_hashes) if (hashes > gpu->max_hashes)
gpu->max_hashes = hashes; gpu->max_hashes = hashes;
status = thrdata->queue_kernel_parameters(clState, &work->blk, globalThreads[0]); /* FOUND entry is used as a counter to say how many nonces exist */
if (unlikely(status != CL_SUCCESS)) {
applog(LOG_ERR, "Error: clSetKernelArg of all params failed.");
return -1;
}
/* MAXBUFFERS entry is used as a flag to say nonces exist */
if (thrdata->res[FOUND]) { if (thrdata->res[FOUND]) {
/* Clear the buffer again */ /* Clear the buffer again */
status = clEnqueueWriteBuffer(clState->commandQueue, clState->outputBuffer, blocking, 0, status = clEnqueueWriteBuffer(clState->commandQueue, clState->outputBuffer, CL_FALSE, 0,
BUFFERSIZE, blank_res, 0, NULL, NULL); BUFFERSIZE, blank_res, 0, NULL, NULL);
if (unlikely(status != CL_SUCCESS)) { if (unlikely(status != CL_SUCCESS)) {
applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed."); applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed.");
@ -1564,15 +1529,26 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
postcalc_hash_async(thr, work, thrdata->res); postcalc_hash_async(thr, work, thrdata->res);
} }
memset(thrdata->res, 0, BUFFERSIZE); memset(thrdata->res, 0, BUFFERSIZE);
if (!blocking)
clFinish(clState->commandQueue); clFinish(clState->commandQueue);
} }
if (gpu->dynamic) {
gettimeofday(&gpu->tv_gpumid, NULL); gettimeofday(&gpu->tv_gpumid, NULL);
if (gpu->new_work) {
gpu->new_work = false;
gpu->intervals = gpu->hit = 0;
}
if (!gpu->intervals) { if (!gpu->intervals) {
gpu->tv_gpustart.tv_sec = gpu->tv_gpumid.tv_sec; gpu->tv_gpustart.tv_sec = gpu->tv_gpumid.tv_sec;
gpu->tv_gpustart.tv_usec = gpu->tv_gpumid.tv_usec; gpu->tv_gpustart.tv_usec = gpu->tv_gpumid.tv_usec;
} }
}
status = thrdata->queue_kernel_parameters(clState, &work->blk, globalThreads[0]);
if (unlikely(status != CL_SUCCESS)) {
applog(LOG_ERR, "Error: clSetKernelArg of all params failed.");
return -1;
}
if (clState->goffset) { if (clState->goffset) {
size_t global_work_offset[1]; size_t global_work_offset[1];
@ -1588,13 +1564,42 @@ static int64_t opencl_scanhash(struct thr_info *thr, struct work *work,
return -1; return -1;
} }
status = clEnqueueReadBuffer(clState->commandQueue, clState->outputBuffer, blocking, 0, status = clEnqueueReadBuffer(clState->commandQueue, clState->outputBuffer, CL_FALSE, 0,
BUFFERSIZE, thrdata->res, 0, NULL, NULL); BUFFERSIZE, thrdata->res, 0, NULL, NULL);
if (unlikely(status != CL_SUCCESS)) { if (unlikely(status != CL_SUCCESS)) {
applog(LOG_ERR, "Error: clEnqueueReadBuffer failed error %d. (clEnqueueReadBuffer)", status); applog(LOG_ERR, "Error: clEnqueueReadBuffer failed error %d. (clEnqueueReadBuffer)", status);
return -1; return -1;
} }
if (gpu->dynamic) {
double gpu_us;
clFinish(clState->commandQueue);
/* Windows returns the same time for gettimeofday due to its
* 15ms timer resolution, so we must average the result over
* at least 5 values that are actually different to get an
* accurate result */
gpu->intervals++;
gettimeofday(&tv_gpuend, NULL);
gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpumid);
if (gpu_us > 0 && ++gpu->hit > 4) {
gpu_us = us_tdiff(&tv_gpuend, &gpu->tv_gpustart) / gpu->intervals;
gpu->gpu_us_average = (gpu->gpu_us_average + gpu_us * 0.63) / 1.63;
/* Try to not let the GPU be out for longer than
* opt_dynamic_interval in ms, but increase
* intensity when the system is idle in dynamic mode */
if (gpu->gpu_us_average > dynamic_us) {
if (gpu->intensity > MIN_INTENSITY)
--gpu->intensity;
} else if (gpu->gpu_us_average < dynamic_us / 2) {
if (gpu->intensity < MAX_INTENSITY)
++gpu->intensity;
}
gpu->intervals = gpu->hit = 0;
}
}
/* The amount of work scanned can fluctuate when intensity changes /* The amount of work scanned can fluctuate when intensity changes
* and since we do this one cycle behind, we increment the work more * and since we do this one cycle behind, we increment the work more
* than enough to prevent repeating work */ * than enough to prevent repeating work */

1
example.conf

@ -33,7 +33,6 @@
"gpu-threads" : "2", "gpu-threads" : "2",
"log" : "5", "log" : "5",
"queue" : "1", "queue" : "1",
"retry-pause" : "5",
"scan-time" : "60", "scan-time" : "60",
"temp-hysteresis" : "3", "temp-hysteresis" : "3",

17
findnonce.c

@ -172,6 +172,7 @@ struct pc_data {
struct work *work; struct work *work;
uint32_t res[MAXBUFFERS]; uint32_t res[MAXBUFFERS];
pthread_t pth; pthread_t pth;
int found;
}; };
static void send_sha_nonce(struct pc_data *pcd, cl_uint nonce) static void send_sha_nonce(struct pc_data *pcd, cl_uint nonce)
@ -237,32 +238,22 @@ static void send_scrypt_nonce(struct pc_data *pcd, uint32_t nonce)
static void *postcalc_hash(void *userdata) static void *postcalc_hash(void *userdata)
{ {
struct pc_data *pcd = (struct pc_data *)userdata; struct pc_data *pcd = (struct pc_data *)userdata;
struct thr_info *thr = pcd->thr; unsigned int entry = 0;
int entry = 0, nonces = 0;
pthread_detach(pthread_self()); pthread_detach(pthread_self());
for (entry = 0; entry < FOUND; entry++) { for (entry = 0; entry < pcd->res[FOUND]; entry++) {
uint32_t nonce = pcd->res[entry]; uint32_t nonce = pcd->res[entry];
if (nonce) { applog(LOG_DEBUG, "OCL NONCE %u found in slot %d", nonce, entry);
applog(LOG_DEBUG, "OCL NONCE %u", nonce);
if (opt_scrypt) if (opt_scrypt)
send_scrypt_nonce(pcd, nonce); send_scrypt_nonce(pcd, nonce);
else else
send_sha_nonce(pcd, nonce); send_sha_nonce(pcd, nonce);
nonces++;
}
} }
free(pcd); free(pcd);
if (unlikely(!nonces)) {
applog(LOG_DEBUG, "No nonces found! Error in OpenCL code?");
hw_errors++;
thr->cgpu->hw_errors++;
}
return NULL; return NULL;
} }

5
findnonce.h

@ -4,10 +4,9 @@
#include "config.h" #include "config.h"
#define MAXTHREADS (0xFFFFFFFEULL) #define MAXTHREADS (0xFFFFFFFEULL)
#define MAXBUFFERS (0xFFF) #define MAXBUFFERS (0x10)
#define BUFFERSIZE (sizeof(uint32_t) * MAXBUFFERS) #define BUFFERSIZE (sizeof(uint32_t) * MAXBUFFERS)
#define FOUND (0x800) #define FOUND (0x0F)
/* #define NFLAG (0x7FF) Just for reference */
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
extern void precalc_hash(dev_blk_ctx *blk, uint32_t *state, uint32_t *data); extern void precalc_hash(dev_blk_ctx *blk, uint32_t *state, uint32_t *data);

6
miner.h

@ -374,6 +374,8 @@ struct cgpu_info {
int intervals, hit; int intervals, hit;
#endif #endif
bool new_work;
float temp; float temp;
int cutofftemp; int cutofftemp;
@ -552,6 +554,7 @@ static inline void rwlock_init(pthread_rwlock_t *lock)
struct pool; struct pool;
extern bool opt_protocol; extern bool opt_protocol;
extern bool have_longpoll;
extern char *opt_kernel_path; extern char *opt_kernel_path;
extern char *opt_socks_proxy; extern char *opt_socks_proxy;
extern char *cgminer_path; extern char *cgminer_path;
@ -595,6 +598,7 @@ extern bool fulltest(const unsigned char *hash, const unsigned char *target);
extern int opt_scantime; extern int opt_scantime;
extern pthread_mutex_t console_lock; extern pthread_mutex_t console_lock;
extern pthread_mutex_t ch_lock;
extern pthread_mutex_t restart_lock; extern pthread_mutex_t restart_lock;
extern pthread_cond_t restart_cond; extern pthread_cond_t restart_cond;
@ -669,6 +673,8 @@ extern unsigned int total_go, total_ro;
extern const int opt_cutofftemp; extern const int opt_cutofftemp;
extern int opt_log_interval; extern int opt_log_interval;
extern unsigned long long global_hashrate; extern unsigned long long global_hashrate;
extern char *current_fullhash;
extern struct timeval block_timeval;
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
typedef struct { typedef struct {

25
miner.php

@ -1,7 +1,7 @@
<?php <?php
session_start(); session_start();
# #
global $miner, $port, $readonly, $notify, $rigs; global $title, $miner, $port, $readonly, $notify, $rigs;
global $rigtotals, $forcerigtotals; global $rigtotals, $forcerigtotals;
global $socksndtimeoutsec, $sockrcvtimeoutsec; global $socksndtimeoutsec, $sockrcvtimeoutsec;
global $checklastshare, $poolinputs, $hidefields; global $checklastshare, $poolinputs, $hidefields;
@ -13,6 +13,9 @@ global $colouroverride, $placebuttons;
# See API-README for more details of these variables and how # See API-README for more details of these variables and how
# to configure miner.php # to configure miner.php
# #
# Web page title
$title = 'Mine';
#
# Set $readonly to true to force miner.php to be readonly # Set $readonly to true to force miner.php to be readonly
# Set $readonly to false then it will check cgminer 'privileged' # Set $readonly to false then it will check cgminer 'privileged'
$readonly = false; $readonly = false;
@ -185,7 +188,7 @@ function getdom($domname)
# #
function htmlhead($checkapi, $rig, $pg = null) function htmlhead($checkapi, $rig, $pg = null)
{ {
global $miner_font_family, $miner_font_size; global $title, $miner_font_family, $miner_font_size;
global $error, $readonly, $poolinputs, $here; global $error, $readonly, $poolinputs, $here;
global $ignorerefresh, $autorefresh; global $ignorerefresh, $autorefresh;
@ -216,7 +219,7 @@ function htmlhead($checkapi, $rig, $pg = null)
$miner_font = "font-family:$miner_font_family; font-size:$miner_font_size;"; $miner_font = "font-family:$miner_font_family; font-size:$miner_font_size;";
echo "<html><head>$refreshmeta echo "<html><head>$refreshmeta
<title>Mine</title> <title>$title</title>
<style type='text/css'> <style type='text/css'>
td { $miner_font ".getcss('td')."} td { $miner_font ".getcss('td')."}
td.two { $miner_font ".getcss('td.two')."} td.two { $miner_font ".getcss('td.two')."}
@ -635,6 +638,10 @@ function fmt($section, $name, $value, $when, $alldata)
$class = $hiclass; $class = $hiclass;
} }
break; break;
case 'SUMMARY.Work Utility':
case 'total.Work Utility':
$ret = $value.'/m';
break;
case 'PGA.Temperature': case 'PGA.Temperature':
case 'GPU.Temperature': case 'GPU.Temperature':
case 'DEVS.Temperature': case 'DEVS.Temperature':
@ -732,6 +739,8 @@ function fmt($section, $name, $value, $when, $alldata)
case 'SUMMARY.Discarded': case 'SUMMARY.Discarded':
case 'POOL.Discarded': case 'POOL.Discarded':
case 'total.Discarded': case 'total.Discarded':
case 'POOL.Diff1 Shares':
case 'total.Diff1 Shares':
$parts = explode('.', $value, 2); $parts = explode('.', $value, 2);
if (count($parts) == 1) if (count($parts) == 1)
$dec = ''; $dec = '';
@ -753,6 +762,7 @@ function fmt($section, $name, $value, $when, $alldata)
$class = $warnclass; $class = $warnclass;
break; break;
case 'STATUS.When': case 'STATUS.When':
case 'COIN.Current Block Time':
$ret = date($dfmt, $value); $ret = date($dfmt, $value);
break; break;
case 'BUTTON.Rig': case 'BUTTON.Rig':
@ -818,7 +828,8 @@ $singlerigsum = array(
'devs' => array('MHS av' => 1, 'MHS 5s' => 1, 'Accepted' => 1, 'Rejected' => 1, 'devs' => array('MHS av' => 1, 'MHS 5s' => 1, 'Accepted' => 1, 'Rejected' => 1,
'Hardware Errors' => 1, 'Utility' => 1, 'Total MH' => 1), 'Hardware Errors' => 1, 'Utility' => 1, 'Total MH' => 1),
'pools' => array('Getworks' => 1, 'Accepted' => 1, 'Rejected' => 1, 'Discarded' => 1, 'pools' => array('Getworks' => 1, 'Accepted' => 1, 'Rejected' => 1, 'Discarded' => 1,
'Stale' => 1, 'Get Failures' => 1, 'Remote Failures' => 1), 'Stale' => 1, 'Get Failures' => 1, 'Remote Failures' => 1,
'Diff1 Shares' => 1),
'notify' => array('*' => 1)); 'notify' => array('*' => 1));
# #
function showtotal($total, $when, $oldvalues) function showtotal($total, $when, $oldvalues)
@ -1447,7 +1458,8 @@ $sectionmap = array(
'NOTIFY' => 'notify', 'NOTIFY' => 'notify',
'DEVDETAILS' => 'devdetails', 'DEVDETAILS' => 'devdetails',
'STATS' => 'stats', 'STATS' => 'stats',
'CONFIG' => 'config'); 'CONFIG' => 'config',
'COIN' => 'coin');
# #
function joinfields($section1, $section2, $join, $results) function joinfields($section1, $section2, $join, $results)
{ {
@ -1582,6 +1594,7 @@ function joinsections($sections, $results, $errors)
case 'POOL': case 'POOL':
case 'DEVS': case 'DEVS':
case 'CONFIG': case 'CONFIG':
case 'COIN':
$sectionmap[$section] = $section; $sectionmap[$section] = $section;
$results[$section] = joinall($both[0], $both[1], $results); $results[$section] = joinall($both[0], $both[1], $results);
break; break;
@ -2023,7 +2036,7 @@ function display()
newtable(); newtable();
doforeach('version', 'rig summary', array(), array(), true); doforeach('version', 'rig summary', array(), array(), true);
$sum = array('MHS av', 'Getworks', 'Found Blocks', 'Accepted', 'Rejected', 'Discarded', 'Stale', 'Utility', 'Local Work', 'Total MH'); $sum = array('MHS av', 'Getworks', 'Found Blocks', 'Accepted', 'Rejected', 'Discarded', 'Stale', 'Utility', 'Local Work', 'Total MH', 'Work Utility', 'Diff1 Shares');
doforeach('summary', 'summary information', $sum, array(), false); doforeach('summary', 'summary information', $sum, array(), false);
endtable(); endtable();
otherrow('<td><br><br></td>'); otherrow('<td><br><br></td>');

162
mkinstalldirs

@ -1,162 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
scriptversion=2009-04-28.21; # UTC
# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain.
#
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
IFS=" "" $nl"
errstatus=0
dirmode=
usage="\
Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
Create each directory DIR (with mode MODE, if specified), including all
leading file name components.
Report bugs to <bug-automake@gnu.org>."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage"
exit $?
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--version)
echo "$0 $scriptversion"
exit $?
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
# mkdir -p a/c at the same time, both will detect that a is missing,
# one will create a, then the other will try to create a and die with
# a "File exists" error. This is a problem when calling mkinstalldirs
# from a parallel make. We use --version in the probe to restrict
# ourselves to GNU mkdir, which is thread-safe.
case $dirmode in
'')
if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
else
# On NextStep and OpenStep, the 'mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because '.' already
# exists.
test -d ./-p && rmdir ./-p
test -d ./--version && rmdir ./--version
fi
;;
*)
if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
test ! -d ./--version; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
else
# Clean up after NextStep and OpenStep mkdir.
for d in ./-m ./-p ./--version "./$dirmode";
do
test -d $d && rmdir $d
done
fi
;;
esac
for file
do
case $file in
/*) pathcomp=/ ;;
*) pathcomp= ;;
esac
oIFS=$IFS
IFS=/
set fnord $file
shift
IFS=$oIFS
for d
do
test "x$d" = x && continue
pathcomp=$pathcomp$d
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp=$pathcomp/
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "; # UTC"
# End:

11
ocl.c

@ -392,7 +392,8 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
strstr(vbuff, "851.4") || // Windows 64 bit "" strstr(vbuff, "851.4") || // Windows 64 bit ""
strstr(vbuff, "831.4") || strstr(vbuff, "831.4") ||
strstr(vbuff, "898.1") || // 12.2 driver SDK strstr(vbuff, "898.1") || // 12.2 driver SDK
strstr(vbuff, "923.1"))) { // 12.4 driver SDK strstr(vbuff, "923.1") || // 12.4
strstr(vbuff, "938.1"))) { // SDK 2.7
applog(LOG_INFO, "Selecting diablo kernel"); applog(LOG_INFO, "Selecting diablo kernel");
clState->chosen_kernel = KL_DIABLO; clState->chosen_kernel = KL_DIABLO;
/* Detect all 7970s, older ATI and NVIDIA and use poclbm */ /* Detect all 7970s, older ATI and NVIDIA and use poclbm */
@ -410,9 +411,9 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
if (clState->chosen_kernel == KL_PHATK && if (clState->chosen_kernel == KL_PHATK &&
(strstr(vbuff, "844.4") || strstr(vbuff, "851.4") || (strstr(vbuff, "844.4") || strstr(vbuff, "851.4") ||
strstr(vbuff, "831.4") || strstr(vbuff, "898.1") || strstr(vbuff, "831.4") || strstr(vbuff, "898.1") ||
strstr(vbuff, "923.1"))) { strstr(vbuff, "923.1") || strstr(vbuff, "938.1"))) {
applog(LOG_WARNING, "WARNING: You have selected the phatk kernel."); applog(LOG_WARNING, "WARNING: You have selected the phatk kernel.");
applog(LOG_WARNING, "You are running SDK 2.6 which performs poorly with this kernel."); applog(LOG_WARNING, "You are running SDK 2.6+ which performs poorly with this kernel.");
applog(LOG_WARNING, "Downgrade your SDK and delete any .bin files before starting again."); applog(LOG_WARNING, "Downgrade your SDK and delete any .bin files before starting again.");
applog(LOG_WARNING, "Or allow cgminer to automatically choose a more suitable kernel."); applog(LOG_WARNING, "Or allow cgminer to automatically choose a more suitable kernel.");
} }
@ -467,8 +468,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
clState->wsize = cgpu->work_size; clState->wsize = cgpu->work_size;
else if (strstr(name, "Tahiti")) else if (strstr(name, "Tahiti"))
clState->wsize = 64; clState->wsize = 64;
else {
if (strstr(name, "Cypress"))
clState->wsize = 256;
else else
clState->wsize = (clState->max_work_size <= 256 ? clState->max_work_size : 256) / clState->vwidth; clState->wsize = (clState->max_work_size <= 256 ? clState->max_work_size : 256) / clState->vwidth;
}
cgpu->work_size = clState->wsize; cgpu->work_size = clState->wsize;
#ifdef USE_SCRYPT #ifdef USE_SCRYPT

51
phatk120724.cl → phatk120823.cl

@ -164,7 +164,7 @@ void search( const uint state0, const uint state1, const uint state2, const uint
const uint PreW18, const uint PreW19, const uint PreW18, const uint PreW19,
const uint PreW31, const uint PreW32, const uint PreW31, const uint PreW32,
__global uint * output) volatile __global uint * output)
{ {
@ -387,31 +387,48 @@ void search( const uint state0, const uint state1, const uint state2, const uint
W[117] += W[108] + Vals[3] + Vals[7] + P2(124) + P1(124) + Ch((Vals[0] + Vals[4]) + (K[59] + W(59+64)) + s1(64+59)+ ch(59+64),Vals[1],Vals[2]) - W[117] += W[108] + Vals[3] + Vals[7] + P2(124) + P1(124) + Ch((Vals[0] + Vals[4]) + (K[59] + W(59+64)) + s1(64+59)+ ch(59+64),Vals[1],Vals[2]) -
(-(K[60] + H[7]) - S1((Vals[0] + Vals[4]) + (K[59] + W(59+64)) + s1(64+59)+ ch(59+64))); (-(K[60] + H[7]) - S1((Vals[0] + Vals[4]) + (K[59] + W(59+64)) + s1(64+59)+ ch(59+64)));
#define FOUND (0x800) #define FOUND (0x0F)
#define NFLAG (0x7FF)
#ifdef VECTORS4 #ifdef VECTORS4
bool result = W[117].x & W[117].y & W[117].z & W[117].w; bool result = W[117].x & W[117].y & W[117].z & W[117].w;
if (!result) { if (!result) {
if (!W[117].x) uint found;
output[FOUND] = output[NFLAG & W[3].x] = W[3].x;
if (!W[117].y) if (!W[117].x) {
output[FOUND] = output[NFLAG & W[3].y] = W[3].y; found = atomic_add(&output[FOUND], 1);
if (!W[117].z) output[found] = W[3].x;
output[FOUND] = output[NFLAG & W[3].z] = W[3].z; }
if (!W[117].w) if (!W[117].y) {
output[FOUND] = output[NFLAG & W[3].w] = W[3].w; found = atomic_add(&output[FOUND], 1);
output[found] = W[3].y;
}
if (!W[117].z) {
found = atomic_add(&output[FOUND], 1);
output[found] = W[3].z;
}
if (!W[117].w) {
found = atomic_add(&output[FOUND], 1);
output[found] = W[3].w;
}
} }
#elif defined VECTORS2 #elif defined VECTORS2
bool result = W[117].x & W[117].y; bool result = W[117].x & W[117].y;
if (!result) { if (!result) {
if (!W[117].x) uint found;
output[FOUND] = output[NFLAG & W[3].x] = W[3].x;
if (!W[117].y) if (!W[117].x) {
output[FOUND] = output[NFLAG & W[3].y] = W[3].y; found = atomic_add(&output[FOUND], 1);
output[found] = W[3].x;
}
if (!W[117].y) {
found = atomic_add(&output[FOUND], 1);
output[found] = W[3].y;
}
} }
#else #else
if (!W[117]) if (!W[117]) {
output[FOUND] = output[NFLAG & W[3]] = W[3]; uint found = atomic_add(&output[FOUND], 1);
output[found] = W[3];
}
#endif #endif
} }

51
poclbm120724.cl → poclbm120823.cl

@ -80,7 +80,7 @@ void search(const uint state0, const uint state1, const uint state2, const uint
const uint D1A, const uint C1addK5, const uint B1addK6, const uint D1A, const uint C1addK5, const uint B1addK6,
const uint W16addK16, const uint W17addK17, const uint W16addK16, const uint W17addK17,
const uint PreVal4addT1, const uint Preval0, const uint PreVal4addT1, const uint Preval0,
__global uint * output) volatile __global uint * output)
{ {
u Vals[24]; u Vals[24];
u *W = &Vals[8]; u *W = &Vals[8];
@ -1311,10 +1311,6 @@ Vals[1]+=(rotr(W[9],17)^rotr(W[9],19)^(W[9]>>10U));
Vals[1]+=K[59]; Vals[1]+=K[59];
Vals[1]+=Vals[5]; Vals[1]+=Vals[5];
#define FOUND (0x800)
#define NFLAG (0x7FF)
#if defined(VECTORS2) || defined(VECTORS4)
Vals[2]+=Ma(Vals[6],Vals[5],Vals[7]); Vals[2]+=Ma(Vals[6],Vals[5],Vals[7]);
Vals[2]+=(rotr(Vals[5],2)^rotr(Vals[5],13)^rotr(Vals[5],22)); Vals[2]+=(rotr(Vals[5],2)^rotr(Vals[5],13)^rotr(Vals[5],22));
Vals[2]+=W[12]; Vals[2]+=W[12];
@ -1325,29 +1321,36 @@ Vals[1]+=Vals[5];
Vals[2]+=(rotr(Vals[1],6)^rotr(Vals[1],11)^rotr(Vals[1],25)); Vals[2]+=(rotr(Vals[1],6)^rotr(Vals[1],11)^rotr(Vals[1],25));
Vals[2]+=ch(Vals[1],Vals[4],Vals[3]); Vals[2]+=ch(Vals[1],Vals[4],Vals[3]);
#define FOUND (0x0F)
#if defined(VECTORS2) || defined(VECTORS4)
if (any(Vals[2] == 0x136032edU)) { if (any(Vals[2] == 0x136032edU)) {
if (Vals[2].x == 0x136032edU) uint found;
output[FOUND] = output[NFLAG & nonce.x] = nonce.x;
if (Vals[2].y == 0x136032edU) if (Vals[2].x == 0x136032edU) {
output[FOUND] = output[NFLAG & nonce.y] = nonce.y; found = atomic_add(&output[FOUND], 1);
output[found] = nonce.x;
}
if (Vals[2].y == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.y;
}
#if defined(VECTORS4) #if defined(VECTORS4)
if (Vals[2].z == 0x136032edU) if (Vals[2].z == 0x136032edU) {
output[FOUND] = output[NFLAG & nonce.z] = nonce.z; found = atomic_add(&output[FOUND], 1);
if (Vals[2].w == 0x136032edU) output[found] = nonce.z;
output[FOUND] = output[NFLAG & nonce.w] = nonce.w; }
if (Vals[2].w == 0x136032edU) {
found = atomic_add(&output[FOUND], 1);
output[found] = nonce.w;
}
#endif #endif
} }
#else #else
if ((Vals[2]+ if (Vals[2] == 0x136032edU) {
Ma(Vals[6],Vals[5],Vals[7])+ uint found = atomic_add(&output[FOUND], 1);
(rotr(Vals[5],2)^rotr(Vals[5],13)^rotr(Vals[5],22))+ output[found] = nonce;
W[12]+ }
(rotr(W[13],7)^rotr(W[13],18)^(W[13]>>3U))+
W[5]+
(rotr(W[10],17)^rotr(W[10],19)^(W[10]>>10U))+
Vals[0]+
(rotr(Vals[1],6)^rotr(Vals[1],11)^rotr(Vals[1],25))+
ch(Vals[1],Vals[4],Vals[3])) == 0x136032edU)
output[FOUND] = output[NFLAG & nonce] = nonce;
#endif #endif
} }

13
scrypt120724.cl → scrypt120823.cl

@ -682,12 +682,11 @@ void scrypt_core(uint4 X[8], __global uint4*restrict lookup)
unshittify(X); unshittify(X);
} }
#define FOUND (0x800) #define FOUND (0x0F)
#define NFLAG (0x7FF)
__attribute__((reqd_work_group_size(WORKSIZE, 1, 1))) __attribute__((reqd_work_group_size(WORKSIZE, 1, 1)))
__kernel void search(__global const uint4 * restrict input, __kernel void search(__global const uint4 * restrict input,
__global uint*restrict output, __global uint4*restrict padcache, volatile __global uint*restrict output, __global uint4*restrict padcache,
const uint4 midstate0, const uint4 midstate16, const uint target) const uint4 midstate0, const uint4 midstate16, const uint target)
{ {
uint gid = get_global_id(0); uint gid = get_global_id(0);
@ -721,9 +720,11 @@ const uint4 midstate0, const uint4 midstate16, const uint target)
SHA256_fixed(&tmp0,&tmp1); SHA256_fixed(&tmp0,&tmp1);
SHA256(&ostate0,&ostate1, tmp0, tmp1, (uint4)(0x80000000U, 0U, 0U, 0U), (uint4)(0U, 0U, 0U, 0x300U)); SHA256(&ostate0,&ostate1, tmp0, tmp1, (uint4)(0x80000000U, 0U, 0U, 0U), (uint4)(0U, 0U, 0U, 0x300U));
bool found = (EndianSwap(ostate1.w) <= target); bool result = (EndianSwap(ostate1.w) <= target);
if (found) if (result) {
output[FOUND] = output[NFLAG & gid] = gid; uint found = atomic_add(&output[FOUND], 1);
output[found] = gid;
}
} }
/*- /*-

39
windows-build.txt

@ -12,6 +12,7 @@ Most of what is described below (copying files, downloading files, etc.) can be
directly in the MinGW MSYS shell; these instructions do not do so because package directly in the MinGW MSYS shell; these instructions do not do so because package
versions and links change over time. The best way is to use your browser, go to the versions and links change over time. The best way is to use your browser, go to the
links directly, and see for yourself which versions you want to install. links directly, and see for yourself which versions you want to install.
Winrar was used to do the extracting of archive files in the making of this guide.
If you think that this documentation was helpful and you wish to donate, you can If you think that this documentation was helpful and you wish to donate, you can
do so at the following address. 12KaKtrK52iQjPdtsJq7fJ7smC32tXWbWr do so at the following address. 12KaKtrK52iQjPdtsJq7fJ7smC32tXWbWr
@ -36,7 +37,7 @@ what you copied.
Go to this url ==> http://www.mingw.org/wiki/Getting_Started Go to this url ==> http://www.mingw.org/wiki/Getting_Started
Click the link that says "Download and run the latest mingw-get-inst version." Click the link that says "Download and run the latest mingw-get-inst version."
Download and run the latest file. Install MinGW in the default directory. Download and run the latest file. Install MinGW in the default directory.
(I downloaded the one labeled "mingw-get-inst-20111118" - note that this could (I downloaded the one labeled "mingw-get-inst-20120426" - note that this could
be a different version later.) be a different version later.)
Make sure to check the option for "Download latest repository catalogs". Make sure to check the option for "Download latest repository catalogs".
I just selected all the check boxes (excluding "Fortran Compiler") so that everything I just selected all the check boxes (excluding "Fortran Compiler") so that everything
@ -138,7 +139,7 @@ in your \MingW\share\aclocal directory.
************************************************************************************** **************************************************************************************
Go to this url ==> http://curl.haxx.se/download.html#Win32 Go to this url ==> http://curl.haxx.se/download.html#Win32
At the section where it says "Win32 - Generic", Click on the link that indicates At the section where it says "Win32 - Generic", Click on the link that indicates
Win32 2000.XP 7.24.0 libcurl SSL and download it. Win32 2000.XP 7.27.0 libcurl SSL and download it.
The one I downloaded may not be current for you. Choose the latest. The one I downloaded may not be current for you. Choose the latest.
Extract the files that are in the zip (bin, include, and lib) to their respective Extract the files that are in the zip (bin, include, and lib) to their respective
locations in MinGW (\MinGW\bin, \MinGW\include, and \MinGW\lib). locations in MinGW (\MinGW\bin, \MinGW\include, and \MinGW\lib).
@ -173,9 +174,9 @@ may be different as well.
*.cl from \MinGW\msys\1.0\home\(username)\cgminer-x.x.x *.cl from \MinGW\msys\1.0\home\(username)\cgminer-x.x.x
README from \MinGW\msys\1.0\home\(username)\cgminer-x.x.x README from \MinGW\msys\1.0\home\(username)\cgminer-x.x.x
libcurl.dll from \MinGW\bin libcurl.dll from \MinGW\bin
libeay32.dll from \MinGW\bin
libidn-11.dll from \MinGW\bin libidn-11.dll from \MinGW\bin
libssl32.dll from \MinGW\bin libeay32.dll from \MinGW\bin
ssleay32.dll from \MinGW\bin
libpdcurses.dll from \MinGW\bin libpdcurses.dll from \MinGW\bin
pthreadGC2.dll from \MinGW\bin pthreadGC2.dll from \MinGW\bin
@ -187,12 +188,13 @@ Click on the Downloads tab.
Download the latest "Portable" git archive. Download the latest "Portable" git archive.
Extract the git*.exe files from the bin folder and put them into \MinGW\bin. Extract the git*.exe files from the bin folder and put them into \MinGW\bin.
Extract the share\git-core folder and place it into \MinGW\share. Extract the share\git-core folder and place it into \MinGW\share.
After the previous step you should have a folder called \MinGW\share\git-core.
To test if it is working, open a MinGW shell and type the following: To test if it is working, open a MinGW shell and type the following:
git config -–global core.autocrlf false (note: one time run only) git config -–global core.autocrlf false (note: one time run only)
git clone git://github.com/ckolivas/cgminer.git git clone git://github.com/ckolivas/cgminer.git
If you simply just want to update the source after you have already cloned, type: If you simply just want to update the source after you have already cloned, type:
git pull git://github.com/ckolivas/cgminer.git git pull
Now you can get the latest source directly from github. Now you can get the latest source directly from github.
@ -209,21 +211,38 @@ From now on when your current working directory is the cgminer source directory
You can simply type "adl.sh" and it will place the ADL header files into place You can simply type "adl.sh" and it will place the ADL header files into place
For you. Make sure you never remove the ADL_SDK folder from your home folder. For you. Make sure you never remove the ADL_SDK folder from your home folder.
**************************************************************************************
* Optional - Install libusb if you need auto USB device detection; required for Ztex *
**************************************************************************************
Go to this url ==> http://libusbx.org/
Click on the "Downloads" tab.
Click on "releases".
Click on the latest version. I downloaded 1.0.12; yours may be newer.
Do not download from the link that says "Looking for the latest version?".
Click on "Windows"
Click on the file and download it. I downloaded libusbx-1.0.12-win.7z.
Extract the the following from the file and place in where directed.
Copy libusb.h from include\libusbx-1.0 to \MinGW\include\libusb-1.0\libusb.h
Copy contents of MinGW32\static \MinGW\lib
Copy contents of MinGW32\dll to \MinGW\lib
You will have to copy "libusb-1.0.dll" to your working cgminer binary directory.
************************************************************************************** **************************************************************************************
* Some ./configure options * * Some ./configure options *
************************************************************************************** **************************************************************************************
--enable-cpumining Build with cpu mining support(default disabled)
--disable-opencl Override detection and disable building with opencl --disable-opencl Override detection and disable building with opencl
--disable-adl Override detection and disable building with adl --disable-adl Override detection and disable building with adl
--enable-bitforce Compile support for BitForce FPGAs(default disabled) --enable-bitforce Compile support for BitForce FPGAs(default disabled)
--enable-icarus Compile support for Icarus Board(default disabled) --enable-icarus Compile support for Icarus Board(default disabled)
--enable-modminer Compile support for ModMiner FPGAs(default disabled)
--enable-ztex Compile support for Ztex Board(default disabled)
--enable-scrypt Compile support for scrypt litecoin mining (default disabled)
--without-curses Compile support for curses TUI (default enabled)
--without-libudev Autodetect FPGAs using libudev (default enabled)
###################################################################################### ######################################################################################
# # # #
# Native WIN32 setup and build instructions (on mingw32/Windows) complete # # Native WIN32 setup and build instructions (on mingw32/Windows) complete #
# # # #
###################################################################################### ######################################################################################
Addendum:
Ztex support requires libusb support. The most comprehensive support is
currently available from the libusbx project here:
http://libusbx.org/

Loading…
Cancel
Save