mirror of
https://github.com/GOSTSec/sgminer
synced 2025-03-13 06:01:03 +00:00
Merge branch 'master' into hashfast
Conflicts: Makefile.am api.c cgminer.c configure.ac miner.h usbutils.c usbutils.h
This commit is contained in:
commit
f49a3c7657
@ -18,3 +18,6 @@ ATTRS{idVendor}=="067b", ATTRS{idProduct}=="0230", SUBSYSTEMS=="usb", ACTION=="a
|
||||
|
||||
# Ztex
|
||||
ATTRS{idVendor}=="221a", ATTRS{idProduct}=="0100", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev"
|
||||
|
||||
# BF1
|
||||
ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev"
|
||||
|
21
ASIC-README
21
ASIC-README
@ -1,10 +1,10 @@
|
||||
SUPPORTED DEVICES
|
||||
|
||||
Currently supported devices include the Avalon (including BitBurner), the
|
||||
Butterfly Labs SC range of devices and the ASICMINER block erupters. No COM
|
||||
ports on windows or TTY devices will be used by cgminer as it communicates
|
||||
directly with them via USB so it is normal for them to not exist or be
|
||||
disconnected when cgminer is running.
|
||||
Butterfly Labs SC range of devices, the ASICMINER block erupters and the BPMC
|
||||
BF1 (bitfury) USB devices. No COM ports on windows or TTY devices will be used
|
||||
by cgminer as it communicates directly with them via USB so it is normal for
|
||||
them to not exist or be disconnected when cgminer is running.
|
||||
|
||||
|
||||
The BFL devices should come up as one of the following:
|
||||
@ -24,7 +24,18 @@ ASICMINER block erupters will come up as AMU.
|
||||
|
||||
ASICMINER devices need the --enable-icarus option when compiling cgminer.
|
||||
Also note that the AMU is managed by the Icarus driver which is detailed
|
||||
in the FPGA-README
|
||||
in the FPGA-README. Configuring them uses the same mechanism as outlined
|
||||
below for getting started with butterfly labs ASICs.
|
||||
|
||||
|
||||
BITFURY devices
|
||||
|
||||
Bitfury devices need the --enable-bitfury option when compiling cgminer.
|
||||
|
||||
Currently only the BPMC BF1 devices AKA redfury/bluefury are supported and
|
||||
come up as BF1. There are no options available for them. Bitfury device are
|
||||
also set up as per the butterfly labs ASICs below.
|
||||
|
||||
|
||||
|
||||
GETTING STARTED WITH BUTTERFLY LABS ASICS
|
||||
|
@ -86,6 +86,14 @@ if HAS_HASHFAST
|
||||
cgminer_SOURCES += driver-hashfast.c driver-hashfast.h
|
||||
endif
|
||||
|
||||
if HAS_BITFURY
|
||||
cgminer_SOURCES += driver-bitfury.c driver-bitfury.h
|
||||
endif
|
||||
|
||||
if HAS_ICARUS
|
||||
cgminer_SOURCES += driver-icarus.c
|
||||
endif
|
||||
|
||||
if HAS_ICARUS
|
||||
cgminer_SOURCES += driver-icarus.c
|
||||
endif
|
||||
|
137
NEWS
137
NEWS
@ -1,3 +1,140 @@
|
||||
Version 3.5.0 - 29th September 2013
|
||||
|
||||
- Add magic init sequence required on BF1 devices to get them mining on windows.
|
||||
- usbinfo.devlock is only ever write locked so convert it to a mutex
|
||||
- Icarus remove unneeded opt_debug tests due to applog being a macro
|
||||
- Icarus - CMR shouldn't wait the full timeout due to handle sharing
|
||||
- We should only yield once in cg_wunlock
|
||||
- Provide a function to downgrade a cglock from a write lock to an intermediate
|
||||
variant.
|
||||
- Deuglify use of _PARSE_COMMANDS macro expansions.
|
||||
- Deuglify use of usb parse commands macro in usbutils.
|
||||
- Use the driver add commands macros in api.c to avoid individually listing
|
||||
them.
|
||||
- Separate out asic fpga and opencl drivers in the driver parse commands macro
|
||||
for use individually as needed.
|
||||
- Use macro expansion in usb_find_devices to avoid explicitly listing them all.
|
||||
- Use macro expansion to iterate over all the drivers without explicitly writing
|
||||
them out in usbutils.c
|
||||
- Iterate over the bitfury offsets in order of decreasing likelihood.
|
||||
- Reattach the kernel driver on linux on usb_uninit.
|
||||
- Attach the kernel driver on failure to usb init on linux.
|
||||
- libusb kernel driver operations are only available on linux.
|
||||
- There is no need to get the external prototypes for drivers in cgminer.c any
|
||||
more.
|
||||
- Remove unnecessary gpu_threads initialisation.
|
||||
- Put avalon last in the sequence of adding drivers to prevent it trying to
|
||||
claim similar chip devices on startup.
|
||||
- Use macro expansion to iterate over all device drivers without needing to
|
||||
explicitly code in support in all places. Pass a hotplug bool to the detect()
|
||||
function to prevent opencl trying to hogplug GPUs.
|
||||
- Forward declare all device drivers in miner.h avoiding the need to export them
|
||||
everywhere else.
|
||||
- Add a noop function for driver detect when it's missing.
|
||||
- Reuse the DRIVER_ macros to avoid having yet another definition for DRV_
|
||||
- Use macro expansion to generate extern device_drv prototypes.
|
||||
- Create a macro list of drivers to enable easier addition of further drivers.
|
||||
- There is no point setting the BF1 preferred packet size to the maximum since
|
||||
it will do so automatically.
|
||||
- icarus ensure all cmr interfaces are initialised properly
|
||||
- usbutils - fix USBDEBUG warnings
|
||||
- Remove unnecessary steps in communicating with BF1 and just use USB interface
|
||||
1.
|
||||
- usbutils - usb_bulk_transfer fix the buf/data fix
|
||||
- usb_bulk_transfer - use the allocated buffer
|
||||
- Set preferred packet sizes per interface on BF1.
|
||||
- usbutils allow PrefPacketSize per endpoint
|
||||
- Remove magic control sequences on open/close on BF1 and just flush the read
|
||||
buffers.
|
||||
- Check return codes in getinfo and reset and fail as needed in BF1.
|
||||
- Check return code for bitfury_open and release resources properly on failed
|
||||
initialisation.
|
||||
- Abstract out flushing of interrupt reads in BF1 devices.
|
||||
- Perform interrupt read after close message on BF1 as per serial close.
|
||||
- Perform interrupt read flush as per serial open on BF1 devices.
|
||||
- Add information for 2nd USB interface on BF1 devices and choose interface 1
|
||||
for bulk transfers.
|
||||
- usbutils - bulk transfer copy test fix
|
||||
- usbutils - add USBDEBUG for usb_bulk_transfer
|
||||
- Add more read_ii variants to usbutils.
|
||||
- Name remainder of BFU usb commands used.
|
||||
- Use submit_tested_work in bitfury driver to avoid unnecessarily re-testing the
|
||||
work for validity.
|
||||
- Abstract out work submission once it's been tested, to be used by drivers that
|
||||
do their own internal validity testing.
|
||||
- Store the hash2 array in struct work for further reuse.
|
||||
- usbutils - which_intinfo not requried
|
||||
- Use the test_nonce function within submit_nonce and store the uint32
|
||||
corresponding to hash2 37 for further use.
|
||||
- usbutils - interfaces must all be on one handle - ep implies the interface
|
||||
- avalon stats use exact type
|
||||
- Only set share diff if we've confirmed it's a share first.
|
||||
- Update ASIC-README for bitfury devices.
|
||||
- Use an array of offsets when checking nonces in bitfury_checkresults
|
||||
- Limit the duration we wait for reads in BF1 based on time already elapsed to
|
||||
account for other delays such as work restart messages or out of work.
|
||||
- Minimise size of serial string we copy in BF1 stats to avoid overflow.
|
||||
- Implement basic API stats for BF1 and increase array of results to check for
|
||||
the rare straggling result.
|
||||
- Space debug output for bf1 to separate from numerals.
|
||||
- Abstract out the bitfury open close and reset functions and use them on
|
||||
reinit.
|
||||
- Rename BF1 devices BF1
|
||||
- Check for work restart, breaking out early after usb reads in BF1.
|
||||
- Do not lose the first sets of results from BF1.
|
||||
- There is no point checking for results from the next round of work on BF1.
|
||||
- Last result returned by BF1 is an end of results marker so ignore it.
|
||||
- restart_wait should return 0 if thr_restart is true.
|
||||
- Remove unused code by bitfury driver since current driver uses serialised
|
||||
scanhash.
|
||||
- Meter out return of estimated hashes in BF1 to smooth out visible hashrate.
|
||||
- Optimise inner scanhash loop for bf1.
|
||||
- Add yet another backup work for triple buffering of work in bf1 to account for
|
||||
extra late results returned and don't check nonce offsets which appear to never
|
||||
return.
|
||||
- Name the work request and result usb commands for BF1
|
||||
- Define a mandatory upper limit to waiting for reset and data on BF1 based on
|
||||
full nonce duration.
|
||||
- Decrease usb buffering to verbose logging.
|
||||
- Add in first draft for a serialised work model sending/receiving data for BF1
|
||||
devices.
|
||||
- Add complete close sequence to bf1 as it happens on serial.
|
||||
- Provide a bitfury identify function for bf1.
|
||||
- Reliably extract BF1 information at startup and reset the device.
|
||||
- Add commands for getting BF1 bitfury info
|
||||
- Add magic BF1 bitfury open and close control sequences.
|
||||
- Add BF1 detection code to bitfury driver.
|
||||
- Create basic placeholders for bitfury driver code.
|
||||
- Add bf1 device information to usbutils to enable device detection.
|
||||
- Add basic defines for building for bitfury devices.
|
||||
- Add redfury device to udev rules.
|
||||
- avalon: display the FPGA controller version on API
|
||||
- pool_active uninitialised_var rolltime
|
||||
- Use macro expansion to only need to define usb enums and commands in one
|
||||
place.
|
||||
- usbutils saving incorrect overflow buffer
|
||||
- ignore libusb.la and *.lo on linux
|
||||
- icarus support CMR with no extensions
|
||||
- usbtils - interfaces dont work yet in libusb windows so disable for that only
|
||||
- Provide a --disable-libcurl config option to build support for stratum mining
|
||||
only.
|
||||
- Fix the api-example.c compile under Linux
|
||||
- usbutils - only release the device once - for the first intinfo
|
||||
- usbutils set_interface is no longer valid
|
||||
- ubsutils interfaces much each have their own handle
|
||||
- usbutils kernel_detach should use the interface number
|
||||
- usbutils - allow the driver to change which_intinfo
|
||||
- Reset quotas on load balance for all pools at the same time to avoid running
|
||||
out during selection and unintentionally dropping to fallback.
|
||||
- Break out of select pool from a common point for appropriate debug messages
|
||||
and to avoid further tests.
|
||||
- usbutils correct/reverse CMR product numbers
|
||||
- usbutils specifically track handles and interfaces
|
||||
- change drivers to use usb_interface() - required for multi interface change
|
||||
- usbutils - allow a device to use multiple interfaces (and better var names)
|
||||
- Cast -1 to (char) to cope with different default char types on ARM.
|
||||
|
||||
|
||||
Version 3.4.3 - 13th September 2013
|
||||
|
||||
- Put corefoundation and iokit separate in ldflags for darwin.
|
||||
|
90
api.c
90
api.c
@ -29,7 +29,7 @@
|
||||
#include "miner.h"
|
||||
#include "util.h"
|
||||
|
||||
#if defined(USE_BFLSC) || defined(USE_AVALON) || defined(USE_HASHFAST)
|
||||
#if defined(USE_BFLSC) || defined(USE_AVALON) || defined(USE_HASHFAST) || defined(USE_BITFURY)
|
||||
#define HAVE_AN_ASIC 1
|
||||
#endif
|
||||
|
||||
@ -167,8 +167,8 @@ static const char *SCRYPTSTR = "scrypt";
|
||||
static const char *SHA256STR = "sha256";
|
||||
|
||||
static const char *DEVICECODE = ""
|
||||
#ifdef HAVE_OPENCL
|
||||
"GPU "
|
||||
#ifdef USE_AVALON
|
||||
"AVA "
|
||||
#endif
|
||||
#ifdef USE_BFLSC
|
||||
"BAS "
|
||||
@ -176,20 +176,23 @@ static const char *DEVICECODE = ""
|
||||
#ifdef USE_BITFORCE
|
||||
"BFL "
|
||||
#endif
|
||||
#ifdef USE_BITFURY
|
||||
"BFU "
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
"GPU "
|
||||
#endif
|
||||
#ifdef USE_HASHFAST
|
||||
"HFA "
|
||||
#endif
|
||||
#ifdef USE_ICARUS
|
||||
"ICA "
|
||||
#endif
|
||||
#ifdef USE_AVALON
|
||||
"AVA "
|
||||
#ifdef USE_MODMINER
|
||||
"MMQ "
|
||||
#endif
|
||||
#ifdef USE_ZTEX
|
||||
"ZTX "
|
||||
#endif
|
||||
#ifdef USE_MODMINER
|
||||
"MMQ "
|
||||
#endif
|
||||
"";
|
||||
|
||||
@ -1211,26 +1214,18 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
|
||||
return root;
|
||||
}
|
||||
|
||||
#define DRIVER_COUNT_DRV(X) if (devices[i]->drv->drv_id == DRIVER_##X) \
|
||||
count++;
|
||||
|
||||
#ifdef HAVE_AN_ASIC
|
||||
static int numascs()
|
||||
static int numascs(void)
|
||||
{
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
rd_lock(&devices_lock);
|
||||
for (i = 0; i < total_devices; i++) {
|
||||
#ifdef USE_AVALON
|
||||
if (devices[i]->drv->drv_id == DRIVER_AVALON)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_BFLSC
|
||||
if (devices[i]->drv->drv_id == DRIVER_BFLSC)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_HASHFAST
|
||||
if (devices[i]->drv->drv_id == DRIVER_HASHFAST)
|
||||
count++;
|
||||
#endif
|
||||
ASIC_PARSE_COMMANDS(DRIVER_COUNT_DRV)
|
||||
}
|
||||
rd_unlock(&devices_lock);
|
||||
return count;
|
||||
@ -1243,18 +1238,7 @@ static int ascdevice(int ascid)
|
||||
|
||||
rd_lock(&devices_lock);
|
||||
for (i = 0; i < total_devices; i++) {
|
||||
#ifdef USE_AVALON
|
||||
if (devices[i]->drv->drv_id == DRIVER_AVALON)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_BFLSC
|
||||
if (devices[i]->drv->drv_id == DRIVER_BFLSC)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_HASHFAST
|
||||
if (devices[i]->drv->drv_id == DRIVER_HASHFAST)
|
||||
count++;
|
||||
#endif
|
||||
ASIC_PARSE_COMMANDS(DRIVER_COUNT_DRV)
|
||||
if (count == (ascid + 1))
|
||||
goto foundit;
|
||||
}
|
||||
@ -1270,29 +1254,14 @@ foundit:
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AN_FPGA
|
||||
static int numpgas()
|
||||
static int numpgas(void)
|
||||
{
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
rd_lock(&devices_lock);
|
||||
for (i = 0; i < total_devices; i++) {
|
||||
#ifdef USE_BITFORCE
|
||||
if (devices[i]->drv->drv_id == DRIVER_BITFORCE)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_ICARUS
|
||||
if (devices[i]->drv->drv_id == DRIVER_ICARUS)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_ZTEX
|
||||
if (devices[i]->drv->drv_id == DRIVER_ZTEX)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_MODMINER
|
||||
if (devices[i]->drv->drv_id == DRIVER_MODMINER)
|
||||
count++;
|
||||
#endif
|
||||
FPGA_PARSE_COMMANDS(DRIVER_COUNT_DRV)
|
||||
}
|
||||
rd_unlock(&devices_lock);
|
||||
return count;
|
||||
@ -1305,22 +1274,7 @@ static int pgadevice(int pgaid)
|
||||
|
||||
rd_lock(&devices_lock);
|
||||
for (i = 0; i < total_devices; i++) {
|
||||
#ifdef USE_BITFORCE
|
||||
if (devices[i]->drv->drv_id == DRIVER_BITFORCE)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_ICARUS
|
||||
if (devices[i]->drv->drv_id == DRIVER_ICARUS)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_ZTEX
|
||||
if (devices[i]->drv->drv_id == DRIVER_ZTEX)
|
||||
count++;
|
||||
#endif
|
||||
#ifdef USE_MODMINER
|
||||
if (devices[i]->drv->drv_id == DRIVER_MODMINER)
|
||||
count++;
|
||||
#endif
|
||||
FPGA_PARSE_COMMANDS(DRIVER_COUNT_DRV)
|
||||
if (count == (pgaid + 1))
|
||||
goto foundit;
|
||||
}
|
||||
@ -1770,11 +1724,11 @@ static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom
|
||||
dev_runtime = 1.0;
|
||||
|
||||
#ifdef USE_ZTEX
|
||||
if (cgpu->drv->drv_id == DRIVER_ZTEX && cgpu->device_ztex)
|
||||
if (cgpu->drv->drv_id == DRIVER_ztex && cgpu->device_ztex)
|
||||
frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1);
|
||||
#endif
|
||||
#ifdef USE_MODMINER
|
||||
if (cgpu->drv->drv_id == DRIVER_MODMINER)
|
||||
if (cgpu->drv->drv_id == DRIVER_modminer)
|
||||
frequency = cgpu->clock;
|
||||
#endif
|
||||
|
||||
|
182
cgminer.c
182
cgminer.c
@ -123,7 +123,7 @@ bool opt_scrypt;
|
||||
#endif
|
||||
#endif
|
||||
bool opt_restart = true;
|
||||
static bool opt_nogpu;
|
||||
bool opt_nogpu;
|
||||
|
||||
struct list_head scan_devices;
|
||||
static bool devices_enabled[MAX_DEVICES];
|
||||
@ -1567,6 +1567,9 @@ static char *opt_verusage_and_exit(const char *extra)
|
||||
#ifdef USE_BITFORCE
|
||||
"bitforce "
|
||||
#endif
|
||||
#ifdef USE_BITFURY
|
||||
"bitfury "
|
||||
#endif
|
||||
#ifdef HAVE_OPENCL
|
||||
"GPU "
|
||||
#endif
|
||||
@ -3662,15 +3665,6 @@ static void rebuild_hash(struct work *work)
|
||||
scrypt_regenhash(work);
|
||||
else
|
||||
regen_hash(work);
|
||||
|
||||
work->share_diff = share_diff(work);
|
||||
if (unlikely(work->share_diff >= current_diff)) {
|
||||
work->block = true;
|
||||
work->pool->solved++;
|
||||
found_blocks++;
|
||||
work->mandatory = true;
|
||||
applog(LOG_NOTICE, "Found block for pool %d!", work->pool->pool_no);
|
||||
}
|
||||
}
|
||||
|
||||
static bool cnx_needed(struct pool *pool);
|
||||
@ -3848,7 +3842,7 @@ int restart_wait(struct thr_info *thr, unsigned int mstime)
|
||||
|
||||
mutex_lock(&restart_lock);
|
||||
if (thr->work_restart)
|
||||
rc = ETIMEDOUT;
|
||||
rc = 0;
|
||||
else
|
||||
rc = pthread_cond_timedwait(&restart_cond, &restart_lock, &abstime);
|
||||
mutex_unlock(&restart_lock);
|
||||
@ -5578,7 +5572,7 @@ static bool pool_active(struct pool *pool, bool pinging)
|
||||
bool ret = false;
|
||||
json_t *val;
|
||||
CURL *curl;
|
||||
int rolltime;
|
||||
int uninitialised_var(rolltime);
|
||||
|
||||
if (pool->has_gbt)
|
||||
applog(LOG_DEBUG, "Retrieving block template from pool %s", pool->rpc_url);
|
||||
@ -6020,17 +6014,12 @@ void inc_hw_errors(struct thr_info *thr)
|
||||
thr->cgpu->drv->hw_error(thr);
|
||||
}
|
||||
|
||||
/* Returns true if nonce for work was a valid share */
|
||||
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
bool test_nonce(struct work *work, uint32_t nonce)
|
||||
{
|
||||
uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12);
|
||||
struct timeval tv_work_found;
|
||||
unsigned char hash2[32];
|
||||
uint32_t *hash2_32 = (uint32_t *)hash2;
|
||||
uint32_t *hash2_32 = (uint32_t *)work->hash2;
|
||||
uint32_t diff1targ;
|
||||
bool ret = true;
|
||||
|
||||
cgtime(&tv_work_found);
|
||||
*work_nonce = htole32(nonce);
|
||||
|
||||
/* Do one last check before attempting to submit the work */
|
||||
@ -6038,14 +6027,16 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
flip32(hash2_32, work->hash);
|
||||
|
||||
diff1targ = opt_scrypt ? 0x0000ffffUL : 0;
|
||||
if (be32toh(hash2_32[7]) > diff1targ) {
|
||||
applog(LOG_INFO, "%s%d: invalid nonce - HW error",
|
||||
thr->cgpu->drv->name, thr->cgpu->device_id);
|
||||
return (be32toh(hash2_32[7]) <= diff1targ);
|
||||
}
|
||||
|
||||
inc_hw_errors(thr);
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
/* To be used once the work has been tested to be meet diff1 and has had its
|
||||
* nonce adjusted. */
|
||||
void submit_tested_work(struct thr_info *thr, struct work *work)
|
||||
{
|
||||
struct timeval tv_work_found;
|
||||
|
||||
work->share_diff = share_diff(work);
|
||||
|
||||
mutex_lock(&stats_lock);
|
||||
total_diff1 += work->device_diff;
|
||||
@ -6054,13 +6045,30 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
thr->cgpu->last_device_valid_work = time(NULL);
|
||||
mutex_unlock(&stats_lock);
|
||||
|
||||
if (!fulltest(hash2, work->target)) {
|
||||
if (!fulltest(work->hash2, work->target)) {
|
||||
applog(LOG_INFO, "Share below target");
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
|
||||
cgtime(&tv_work_found);
|
||||
submit_work_async(work, &tv_work_found);
|
||||
out:
|
||||
}
|
||||
|
||||
/* Returns true if nonce for work was a valid share */
|
||||
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
if (test_nonce(work, nonce))
|
||||
submit_tested_work(thr, work);
|
||||
else {
|
||||
applog(LOG_INFO, "%s%d: invalid nonce - HW error",
|
||||
thr->cgpu->drv->name, thr->cgpu->device_id);
|
||||
|
||||
inc_hw_errors(thr);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -7351,34 +7359,6 @@ void enable_curses(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BFLSC
|
||||
extern struct device_drv bflsc_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_BITFORCE
|
||||
extern struct device_drv bitforce_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_HASHFAST
|
||||
extern struct device_drv hashfast_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_ICARUS
|
||||
extern struct device_drv icarus_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_AVALON
|
||||
extern struct device_drv avalon_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODMINER
|
||||
extern struct device_drv modminer_drv;
|
||||
#endif
|
||||
|
||||
#ifdef USE_ZTEX
|
||||
extern struct device_drv ztex_drv;
|
||||
#endif
|
||||
|
||||
static int cgminer_id_count = 0;
|
||||
|
||||
/* Various noop functions for drivers that don't support or need their
|
||||
@ -7433,14 +7413,17 @@ static void noop_thread_enable(struct thr_info __maybe_unused *thr)
|
||||
{
|
||||
}
|
||||
|
||||
static void noop_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
}
|
||||
#define noop_flush_work noop_reinit_device
|
||||
#define noop_queue_full noop_get_stats
|
||||
|
||||
/* Fill missing driver drv functions with noops */
|
||||
void fill_device_drv(struct cgpu_info *cgpu)
|
||||
void fill_device_drv(struct device_drv *drv)
|
||||
{
|
||||
struct device_drv *drv = cgpu->drv;
|
||||
|
||||
if (!drv->drv_detect)
|
||||
drv->drv_detect = &noop_detect;
|
||||
if (!drv->reinit_device)
|
||||
drv->reinit_device = &noop_reinit_device;
|
||||
if (!drv->get_statline_before)
|
||||
@ -7495,7 +7478,7 @@ void enable_device(struct cgpu_info *cgpu)
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_OPENCL
|
||||
if (cgpu->drv->drv_id == DRIVER_OPENCL) {
|
||||
if (cgpu->drv->drv_id == DRIVER_opencl) {
|
||||
gpu_threads += cgpu->threads;
|
||||
}
|
||||
#endif
|
||||
@ -7538,8 +7521,6 @@ bool add_cgpu(struct cgpu_info *cgpu)
|
||||
cgpu->last_device_valid_work = time(NULL);
|
||||
mutex_unlock(&stats_lock);
|
||||
|
||||
fill_device_drv(cgpu);
|
||||
|
||||
if (hotplug_mode)
|
||||
devices[total_devices + new_devices++] = cgpu;
|
||||
else
|
||||
@ -7630,6 +7611,8 @@ static void hotplug_process()
|
||||
switch_logsize(true);
|
||||
}
|
||||
|
||||
#define DRIVER_DRV_DETECT_HOTPLUG(X) X##_drv.drv_detect(true);
|
||||
|
||||
static void *hotplug_thread(void __maybe_unused *userdata)
|
||||
{
|
||||
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
|
||||
@ -7649,29 +7632,9 @@ static void *hotplug_thread(void __maybe_unused *userdata)
|
||||
new_devices = 0;
|
||||
new_threads = 0;
|
||||
|
||||
#ifdef USE_ICARUS
|
||||
icarus_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_BFLSC
|
||||
bflsc_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_BITFORCE
|
||||
bitforce_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_HASHFAST
|
||||
hashfast_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODMINER
|
||||
modminer_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_AVALON
|
||||
avalon_drv.drv_detect();
|
||||
#endif
|
||||
/* Use the DRIVER_PARSE_COMMANDS macro to detect all
|
||||
* devices */
|
||||
DRIVER_PARSE_COMMANDS(DRIVER_DRV_DETECT_HOTPLUG)
|
||||
|
||||
if (new_devices)
|
||||
hotplug_process();
|
||||
@ -7697,6 +7660,9 @@ static void probe_pools(void)
|
||||
}
|
||||
}
|
||||
|
||||
#define DRIVER_FILL_DEVICE_DRV(X) fill_device_drv(&X##_drv);
|
||||
#define DRIVER_DRV_DETECT_ALL(X) X##_drv.drv_detect(false);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sigaction handler;
|
||||
@ -7877,44 +7843,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
if (!opt_nogpu)
|
||||
opencl_drv.drv_detect();
|
||||
gpu_threads = 0;
|
||||
#endif
|
||||
/* Use the DRIVER_PARSE_COMMANDS macro to fill all the device_drvs */
|
||||
DRIVER_PARSE_COMMANDS(DRIVER_FILL_DEVICE_DRV)
|
||||
|
||||
if (!opt_scrypt) {
|
||||
#ifdef USE_ICARUS
|
||||
icarus_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_BFLSC
|
||||
bflsc_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_BITFORCE
|
||||
bitforce_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_HASHFAST
|
||||
hf_init_crc8();
|
||||
hf_init_crc32();
|
||||
hashfast_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODMINER
|
||||
modminer_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
#ifdef USE_ZTEX
|
||||
ztex_drv.drv_detect();
|
||||
#endif
|
||||
|
||||
/* Detect avalon last since it will try to claim the device regardless
|
||||
* as detection is unreliable. */
|
||||
#ifdef USE_AVALON
|
||||
avalon_drv.drv_detect();
|
||||
#endif
|
||||
if (opt_scrypt)
|
||||
opencl_drv.drv_detect(false);
|
||||
else {
|
||||
/* Use the DRIVER_PARSE_COMMANDS macro to detect all devices */
|
||||
DRIVER_PARSE_COMMANDS(DRIVER_DRV_DETECT_ALL)
|
||||
}
|
||||
|
||||
if (opt_display_devs) {
|
||||
|
27
configure.ac
27
configure.ac
@ -1,8 +1,8 @@
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
m4_define([v_maj], [3])
|
||||
m4_define([v_min], [4])
|
||||
m4_define([v_mic], [3])
|
||||
m4_define([v_min], [5])
|
||||
m4_define([v_mic], [0])
|
||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||
m4_define([v_ver], [v_maj.v_min.v_mic])
|
||||
m4_define([lt_rev], m4_eval(v_maj + v_min))
|
||||
@ -253,6 +253,17 @@ if test "x$bitforce" = xyes; then
|
||||
fi
|
||||
AM_CONDITIONAL([HAS_BITFORCE], [test x$bitforce = xyes])
|
||||
|
||||
bitfury="no"
|
||||
|
||||
AC_ARG_ENABLE([bitfury],
|
||||
[AC_HELP_STRING([--enable-bitfury],[Compile support for BitFury ASICs (default disabled)])],
|
||||
[bitfury=$enableval]
|
||||
)
|
||||
if test "x$bitfury" = xyes; then
|
||||
AC_DEFINE([USE_BITFURY], [1], [Defined to 1 if BitForce support is wanted])
|
||||
fi
|
||||
AM_CONDITIONAL([HAS_BITFURY], [test x$bitfury = xyes])
|
||||
|
||||
hashfast="no"
|
||||
|
||||
AC_ARG_ENABLE([hashfast],
|
||||
@ -321,7 +332,7 @@ else
|
||||
])
|
||||
fi
|
||||
|
||||
if test x$avalon$bitforce$modminer$bflsc$icarus$hashfast != xnononononono; then
|
||||
if test x$avalon$bitforce$bitfury$modminer$bflsc$icarus$hashfast != xnonononononono; then
|
||||
want_usbutils=true
|
||||
else
|
||||
want_usbutils=false
|
||||
@ -493,14 +504,14 @@ if test "x$opencl" != xno; then
|
||||
|
||||
else
|
||||
echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED"
|
||||
if test "x$bitforce$avalon$icarus$ztex$modminer$bflsc$hashfast" = xnonononononono; then
|
||||
if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc$hashfast" = xnononononononono; then
|
||||
AC_MSG_ERROR([No mining configured in])
|
||||
fi
|
||||
echo " scrypt...............: Disabled (needs OpenCL)"
|
||||
fi
|
||||
else
|
||||
echo " OpenCL...............: Detection overrided. GPU mining support DISABLED"
|
||||
if test "x$bitforce$icarus$avalon$ztex$modminer$bflsc$hashfast" = xnonononononono; then
|
||||
if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc$hashfast" = xnononononononono; then
|
||||
AC_MSG_ERROR([No mining configured in])
|
||||
fi
|
||||
echo " scrypt...............: Disabled (needs OpenCL)"
|
||||
@ -535,6 +546,12 @@ else
|
||||
echo " BitForce.FPGAs.......: Disabled"
|
||||
fi
|
||||
|
||||
if test "x$bitfury" = xyes; then
|
||||
echo " BitFury.ASICs........: Enabled"
|
||||
else
|
||||
echo " BitFury.ASICs........: Disabled"
|
||||
fi
|
||||
|
||||
if test "x$hashfast" = xyes; then
|
||||
echo " Hashfast.ASICs.......: Enabled"
|
||||
else
|
||||
|
@ -52,7 +52,6 @@ int opt_bitburner_core_voltage = BITBURNER_DEFAULT_CORE_VOLTAGE;
|
||||
bool opt_avalon_auto;
|
||||
|
||||
static int option_offset = -1;
|
||||
struct device_drv avalon_drv;
|
||||
|
||||
static int avalon_init_task(struct avalon_task *at,
|
||||
uint8_t reset, uint8_t ff, uint8_t fan,
|
||||
@ -273,6 +272,7 @@ static int avalon_reset(struct cgpu_info *avalon, bool initial)
|
||||
struct avalon_task at;
|
||||
uint8_t *buf, *tmp;
|
||||
struct timespec p;
|
||||
struct avalon_info *info = avalon->device_data;
|
||||
|
||||
/* Send reset, then check for result */
|
||||
avalon_init_task(&at, 1, 0,
|
||||
@ -329,9 +329,17 @@ static int avalon_reset(struct cgpu_info *avalon, bool initial)
|
||||
" (%d: %02x %02x %02x %02x)", avalon->drv->name, avalon->device_id,
|
||||
i, buf[0], buf[1], buf[2], buf[3]);
|
||||
/* FIXME: return 1; */
|
||||
} else
|
||||
applog(LOG_WARNING, "%s%d: Reset succeeded",
|
||||
avalon->drv->name, avalon->device_id);
|
||||
} else {
|
||||
/* buf[44]: minor
|
||||
* buf[45]: day
|
||||
* buf[46]: year,month, d6: 201306
|
||||
*/
|
||||
info->ctlr_ver = ((buf[46] >> 4) + 2000) * 1000000 +
|
||||
(buf[46] & 0x0f) * 10000 +
|
||||
buf[45] * 100 + buf[44];
|
||||
applog(LOG_WARNING, "%s%d: Reset succeeded (Controller version: %d)",
|
||||
avalon->drv->name, avalon->device_id, info->ctlr_ver);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -711,7 +719,7 @@ static bool avalon_detect_one(libusb_device *dev, struct usb_find_devices *found
|
||||
/* Even though this is an FTDI type chip, we want to do the parsing
|
||||
* all ourselves so set it to std usb type */
|
||||
avalon->usbdev->usb_type = USB_TYPE_STD;
|
||||
avalon->usbdev->PrefPacketSize = AVALON_USB_PACKETSIZE;
|
||||
usb_set_pps(avalon, AVALON_USB_PACKETSIZE);
|
||||
|
||||
/* We have a real Avalon! */
|
||||
avalon_initialise(avalon);
|
||||
@ -791,7 +799,7 @@ shin:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void avalon_detect(void)
|
||||
static void avalon_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&avalon_drv, avalon_detect_one);
|
||||
}
|
||||
@ -1522,6 +1530,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)
|
||||
info->version1, info->version2, info->version3);
|
||||
root = api_add_string(root, "version", buf, true);
|
||||
}
|
||||
root = api_add_uint32(root, "Controller Version", &(info->ctlr_ver), false);
|
||||
|
||||
return root;
|
||||
}
|
||||
@ -1590,7 +1599,7 @@ static char *avalon_set_device(struct cgpu_info *avalon, char *option, char *set
|
||||
}
|
||||
|
||||
struct device_drv avalon_drv = {
|
||||
.drv_id = DRIVER_AVALON,
|
||||
.drv_id = DRIVER_avalon,
|
||||
.dname = "avalon",
|
||||
.name = "AVA",
|
||||
.drv_detect = avalon_detect,
|
||||
|
@ -125,6 +125,7 @@ struct avalon_info {
|
||||
int matching_work[AVALON_DEFAULT_MINER_NUM];
|
||||
|
||||
int frequency;
|
||||
uint32_t ctlr_ver;
|
||||
|
||||
struct thr_info *thr;
|
||||
pthread_t read_thr;
|
||||
|
@ -33,8 +33,6 @@ int opt_bflsc_overheat = BFLSC_TEMP_OVERHEAT;
|
||||
|
||||
static const char *blank = "";
|
||||
|
||||
struct device_drv bflsc_drv;
|
||||
|
||||
static enum driver_version drv_ver(struct cgpu_info *bflsc, const char *ver)
|
||||
{
|
||||
char *tmp;
|
||||
@ -895,7 +893,7 @@ shin:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bflsc_detect(void)
|
||||
static void bflsc_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&bflsc_drv, bflsc_detect_one);
|
||||
}
|
||||
@ -1915,7 +1913,7 @@ else a whole lot of something like these ... etc
|
||||
}
|
||||
|
||||
struct device_drv bflsc_drv = {
|
||||
.drv_id = DRIVER_BFLSC,
|
||||
.drv_id = DRIVER_bflsc,
|
||||
.dname = "BitForceSC",
|
||||
.name = BFLSC_SINGLE,
|
||||
.drv_detect = bflsc_detect,
|
||||
|
@ -77,8 +77,6 @@
|
||||
|
||||
static const char *blank = "";
|
||||
|
||||
struct device_drv bitforce_drv;
|
||||
|
||||
static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
|
||||
{
|
||||
int err, interface;
|
||||
@ -290,7 +288,7 @@ shin:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bitforce_detect(void)
|
||||
static void bitforce_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&bitforce_drv, bitforce_detect_one);
|
||||
}
|
||||
@ -742,7 +740,7 @@ static struct api_data *bitforce_api_stats(struct cgpu_info *cgpu)
|
||||
}
|
||||
|
||||
struct device_drv bitforce_drv = {
|
||||
.drv_id = DRIVER_BITFORCE,
|
||||
.drv_id = DRIVER_bitforce,
|
||||
.dname = "BitForce",
|
||||
.name = "BFL",
|
||||
.drv_detect = bitforce_detect,
|
||||
|
330
driver-bitfury.c
Normal file
330
driver-bitfury.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright 2013 Con Kolivas
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "miner.h"
|
||||
#include "driver-bitfury.h"
|
||||
#include "sha2.h"
|
||||
|
||||
/* Wait longer 1/3 longer than it would take for a full nonce range */
|
||||
#define BF1WAIT 1600
|
||||
|
||||
static void bitfury_empty_buffer(struct cgpu_info *bitfury)
|
||||
{
|
||||
char buf[512];
|
||||
int amount;
|
||||
|
||||
do {
|
||||
usb_read_once(bitfury, buf, 512, &amount, C_BF1_FLUSH);
|
||||
} while (amount);
|
||||
}
|
||||
|
||||
static void bitfury_open(struct cgpu_info *bitfury)
|
||||
{
|
||||
uint32_t buf[2];
|
||||
|
||||
bitfury_empty_buffer(bitfury);
|
||||
/* Magic sequence to reset device only really needed for windows but
|
||||
* harmless on linux. */
|
||||
buf[0] = 0x80250000;
|
||||
buf[1] = 0x00000800;
|
||||
usb_transfer(bitfury, 0, 9, 1, 0, C_BF1_RESET);
|
||||
usb_transfer(bitfury, 0x21, 0x22, 0, 0, C_BF1_OPEN);
|
||||
usb_transfer_data(bitfury, 0x21, 0x20, 0x0000, 0, buf, 7, C_BF1_INIT);
|
||||
}
|
||||
|
||||
static void bitfury_close(struct cgpu_info *bitfury)
|
||||
{
|
||||
bitfury_empty_buffer(bitfury);
|
||||
}
|
||||
|
||||
static void bitfury_identify(struct cgpu_info *bitfury)
|
||||
{
|
||||
int amount;
|
||||
|
||||
usb_write(bitfury, "L", 1, &amount, C_BF1_IDENTIFY);
|
||||
}
|
||||
|
||||
static bool bitfury_getinfo(struct cgpu_info *bitfury, struct bitfury_info *info)
|
||||
{
|
||||
int amount, err;
|
||||
char buf[16];
|
||||
|
||||
err = usb_write(bitfury, "I", 1, &amount, C_BF1_REQINFO);
|
||||
if (err) {
|
||||
applog(LOG_INFO, "%s %d: Failed to write REQINFO",
|
||||
bitfury->drv->name, bitfury->device_id);
|
||||
return false;
|
||||
}
|
||||
err = usb_read(bitfury, buf, 14, &amount, C_BF1_GETINFO);
|
||||
if (err) {
|
||||
applog(LOG_INFO, "%s %d: Failed to read GETINFO",
|
||||
bitfury->drv->name, bitfury->device_id);
|
||||
return false;
|
||||
}
|
||||
if (amount != 14) {
|
||||
applog(LOG_INFO, "%s %d: Getinfo received %d bytes instead of 14",
|
||||
bitfury->drv->name, bitfury->device_id, amount);
|
||||
return false;
|
||||
}
|
||||
info->version = buf[1];
|
||||
memcpy(&info->product, buf + 2, 8);
|
||||
memcpy(&info->serial, buf + 10, 4);
|
||||
|
||||
applog(LOG_INFO, "%s %d: Getinfo returned version %d, product %s serial %08x", bitfury->drv->name,
|
||||
bitfury->device_id, info->version, info->product, info->serial);
|
||||
bitfury_empty_buffer(bitfury);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bitfury_reset(struct cgpu_info *bitfury)
|
||||
{
|
||||
int amount, err;
|
||||
char buf[16];
|
||||
|
||||
err = usb_write(bitfury, "R", 1, &amount, C_BF1_REQRESET);
|
||||
if (err) {
|
||||
applog(LOG_INFO, "%s %d: Failed to write REQRESET",
|
||||
bitfury->drv->name, bitfury->device_id);
|
||||
return false;
|
||||
}
|
||||
err = usb_read_timeout(bitfury, buf, 7, &amount, BF1WAIT, C_BF1_GETRESET);
|
||||
if (err) {
|
||||
applog(LOG_INFO, "%s %d: Failed to read GETRESET",
|
||||
bitfury->drv->name, bitfury->device_id);
|
||||
return false;
|
||||
}
|
||||
if (amount != 7) {
|
||||
applog(LOG_INFO, "%s %d: Getreset received %d bytes instead of 7",
|
||||
bitfury->drv->name, bitfury->device_id, amount);
|
||||
return false;
|
||||
}
|
||||
applog(LOG_DEBUG, "%s %d: Getreset returned %s", bitfury->drv->name,
|
||||
bitfury->device_id, buf);
|
||||
bitfury_empty_buffer(bitfury);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool bitfury_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
|
||||
{
|
||||
struct cgpu_info *bitfury;
|
||||
struct bitfury_info *info;
|
||||
|
||||
bitfury = usb_alloc_cgpu(&bitfury_drv, 1);
|
||||
|
||||
if (!usb_init(bitfury, dev, found))
|
||||
goto out;
|
||||
applog(LOG_INFO, "%s %d: Found at %s", bitfury->drv->name,
|
||||
bitfury->device_id, bitfury->device_path);
|
||||
|
||||
info = calloc(sizeof(struct bitfury_info), 1);
|
||||
if (!info)
|
||||
quit(1, "Failed to calloc info in bitfury_detect_one");
|
||||
bitfury->device_data = info;
|
||||
|
||||
usb_buffer_enable(bitfury);
|
||||
|
||||
bitfury_open(bitfury);
|
||||
|
||||
/* Send getinfo request */
|
||||
if (!bitfury_getinfo(bitfury, info))
|
||||
goto out_close;
|
||||
|
||||
/* Send reset request */
|
||||
if (!bitfury_reset(bitfury))
|
||||
goto out_close;
|
||||
|
||||
bitfury_identify(bitfury);
|
||||
bitfury_empty_buffer(bitfury);
|
||||
|
||||
if (!add_cgpu(bitfury))
|
||||
goto out_close;
|
||||
|
||||
update_usb_stats(bitfury);
|
||||
applog(LOG_INFO, "%s %d: Found at %s",
|
||||
bitfury->drv->name, bitfury->device_id, bitfury->device_path);
|
||||
return true;
|
||||
out_close:
|
||||
bitfury_close(bitfury);
|
||||
usb_uninit(bitfury);
|
||||
out:
|
||||
bitfury = usb_free_cgpu(bitfury);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void bitfury_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&bitfury_drv, bitfury_detect_one);
|
||||
}
|
||||
|
||||
static uint32_t decnonce(uint32_t in)
|
||||
{
|
||||
uint32_t out;
|
||||
|
||||
/* First part load */
|
||||
out = (in & 0xFF) << 24; in >>= 8;
|
||||
|
||||
/* Byte reversal */
|
||||
in = (((in & 0xaaaaaaaa) >> 1) | ((in & 0x55555555) << 1));
|
||||
in = (((in & 0xcccccccc) >> 2) | ((in & 0x33333333) << 2));
|
||||
in = (((in & 0xf0f0f0f0) >> 4) | ((in & 0x0f0f0f0f) << 4));
|
||||
|
||||
out |= (in >> 2)&0x3FFFFF;
|
||||
|
||||
/* Extraction */
|
||||
if (in & 1) out |= (1 << 23);
|
||||
if (in & 2) out |= (1 << 22);
|
||||
|
||||
out -= 0x800004;
|
||||
return out;
|
||||
}
|
||||
|
||||
#define BT_OFFSETS 3
|
||||
const uint32_t bf_offsets[] = {-0x800000, 0, -0x400000};
|
||||
|
||||
static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BT_OFFSETS; i++) {
|
||||
if (test_nonce(work, nonce + bf_offsets[i])) {
|
||||
submit_tested_work(thr, work);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
|
||||
int64_t __maybe_unused max_nonce)
|
||||
{
|
||||
struct cgpu_info *bitfury = thr->cgpu;
|
||||
struct bitfury_info *info = bitfury->device_data;
|
||||
struct timeval tv_now;
|
||||
int amount, i;
|
||||
char buf[45];
|
||||
int ms_diff;
|
||||
|
||||
buf[0] = 'W';
|
||||
memcpy(buf + 1, work->midstate, 32);
|
||||
memcpy(buf + 33, work->data + 64, 12);
|
||||
|
||||
/* New results may spill out from the latest work, making us drop out
|
||||
* too early so read whatever we get for the first half nonce and then
|
||||
* look for the results to prev work. */
|
||||
cgtime(&tv_now);
|
||||
ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start);
|
||||
if (ms_diff > 0) {
|
||||
usb_read_timeout(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES);
|
||||
info->tot += amount;
|
||||
}
|
||||
|
||||
if (unlikely(thr->work_restart))
|
||||
goto cascade;
|
||||
|
||||
/* Now look for the bulk of the previous work results, they will come
|
||||
* in a batch following the first data. */
|
||||
cgtime(&tv_now);
|
||||
ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start);
|
||||
if (unlikely(ms_diff < 10))
|
||||
ms_diff = 10;
|
||||
usb_read_once_timeout(bitfury, info->buf + info->tot, 7, &amount, ms_diff, C_BF1_GETRES);
|
||||
info->tot += amount;
|
||||
while (amount) {
|
||||
usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES);
|
||||
info->tot += amount;
|
||||
};
|
||||
|
||||
if (unlikely(thr->work_restart))
|
||||
goto cascade;
|
||||
|
||||
/* Send work */
|
||||
usb_write(bitfury, buf, 45, &amount, C_BF1_REQWORK);
|
||||
cgtime(&info->tv_start);
|
||||
/* Get response acknowledging work */
|
||||
usb_read(bitfury, buf, 7, &amount, C_BF1_GETWORK);
|
||||
|
||||
/* Only happens on startup */
|
||||
if (unlikely(!info->prevwork[BF1ARRAY_SIZE]))
|
||||
goto cascade;
|
||||
|
||||
/* Search for what work the nonce matches in order of likelihood. Last
|
||||
* entry is end of result marker. */
|
||||
for (i = 0; i < info->tot - 7; i += 7) {
|
||||
uint32_t nonce;
|
||||
int j;
|
||||
|
||||
/* Ignore state & switched data in results for now. */
|
||||
memcpy(&nonce, info->buf + i + 3, 4);
|
||||
nonce = decnonce(nonce);
|
||||
for (j = 0; j < BF1ARRAY_SIZE; j++) {
|
||||
if (bitfury_checkresults(thr, info->prevwork[j], nonce)) {
|
||||
info->nonces++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->tot = 0;
|
||||
free_work(info->prevwork[BF1ARRAY_SIZE]);
|
||||
cascade:
|
||||
for (i = BF1ARRAY_SIZE; i > 0; i--)
|
||||
info->prevwork[i] = info->prevwork[i - 1];
|
||||
info->prevwork[0] = copy_work(work);
|
||||
work->blk.nonce = 0xffffffff;
|
||||
if (info->nonces) {
|
||||
info->nonces--;
|
||||
return (int64_t)0xffffffff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct api_data *bitfury_api_stats(struct cgpu_info *cgpu)
|
||||
{
|
||||
struct bitfury_info *info = cgpu->device_data;
|
||||
struct api_data *root = NULL;
|
||||
char serial[16];
|
||||
int version;
|
||||
|
||||
version = info->version;
|
||||
root = api_add_int(root, "Version", &version, true);
|
||||
root = api_add_string(root, "Product", info->product, false);
|
||||
sprintf(serial, "%08x", info->serial);
|
||||
root = api_add_string(root, "Serial", serial, true);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
static void bitfury_init(struct cgpu_info *bitfury)
|
||||
{
|
||||
bitfury_close(bitfury);
|
||||
bitfury_open(bitfury);
|
||||
bitfury_reset(bitfury);
|
||||
}
|
||||
|
||||
static void bitfury_shutdown(struct thr_info *thr)
|
||||
{
|
||||
struct cgpu_info *bitfury = thr->cgpu;
|
||||
|
||||
bitfury_close(bitfury);
|
||||
}
|
||||
|
||||
/* Currently hardcoded to BF1 devices */
|
||||
struct device_drv bitfury_drv = {
|
||||
.drv_id = DRIVER_bitfury,
|
||||
.dname = "bitfury",
|
||||
.name = "BF1",
|
||||
.drv_detect = bitfury_detect,
|
||||
.scanhash = bitfury_scanhash,
|
||||
.get_api_stats = bitfury_api_stats,
|
||||
.reinit_device = bitfury_init,
|
||||
.thread_shutdown = bitfury_shutdown,
|
||||
.identify_device = bitfury_identify
|
||||
};
|
30
driver-bitfury.h
Normal file
30
driver-bitfury.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2013 Con Kolivas
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef BITFURY_H
|
||||
#define BITFURY_H
|
||||
|
||||
#include "miner.h"
|
||||
#include "usbutils.h"
|
||||
|
||||
#define BF1ARRAY_SIZE 2
|
||||
|
||||
struct bitfury_info {
|
||||
struct cgpu_info *base_cgpu;
|
||||
uint8_t version;
|
||||
char product[8];
|
||||
uint32_t serial;
|
||||
struct work *prevwork[BF1ARRAY_SIZE + 1];
|
||||
char buf[512];
|
||||
int tot;
|
||||
int nonces;
|
||||
struct timeval tv_start;
|
||||
};
|
||||
|
||||
#endif /* BITFURY_H */
|
@ -285,7 +285,7 @@ static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices
|
||||
}
|
||||
|
||||
hashfast->usbdev->usb_type = USB_TYPE_STD;
|
||||
hashfast->usbdev->PrefPacketSize = HASHFAST_USB_PACKETSIZE;
|
||||
usb_set_pps(hashfast, HASHFAST_USB_PACKETSIZE);
|
||||
|
||||
hashfast_usb_initialise(hashfast);
|
||||
|
||||
@ -293,8 +293,13 @@ static bool hashfast_detect_one_usb(libusb_device *dev, struct usb_find_devices
|
||||
return hashfast_detect_common(hashfast, baud);
|
||||
}
|
||||
|
||||
static void hashfast_detect(void)
|
||||
static void hashfast_detect(bool hotplug)
|
||||
{
|
||||
/* Set up the CRC tables only once. */
|
||||
if (!hotplug) {
|
||||
hf_init_crc8();
|
||||
hf_init_crc32();
|
||||
}
|
||||
usb_detect(&hashfast_drv, hashfast_detect_one_usb);
|
||||
}
|
||||
|
||||
@ -328,7 +333,7 @@ static void hashfast_shutdown(struct thr_info __maybe_unused *thr)
|
||||
}
|
||||
|
||||
struct device_drv hashfast_drv = {
|
||||
.drv_id = DRIVER_HASHFAST,
|
||||
.drv_id = DRIVER_hashfast,
|
||||
.dname = "Hashfast",
|
||||
.name = "HFA",
|
||||
.drv_detect = hashfast_detect,
|
||||
|
103
driver-icarus.c
103
driver-icarus.c
@ -74,6 +74,7 @@ ASSERT1(sizeof(uint32_t) == 4);
|
||||
|
||||
// USB ms timeout to wait - user specified timeouts are multiples of this
|
||||
#define ICARUS_WAIT_TIMEOUT 100
|
||||
#define ICARUS_CMR2_TIMEOUT 1
|
||||
|
||||
// Defined in multiples of ICARUS_WAIT_TIMEOUT
|
||||
// Must of course be greater than ICARUS_READ_COUNT_TIMING/ICARUS_WAIT_TIMEOUT
|
||||
@ -177,6 +178,8 @@ static const char *MODE_VALUE_STR = "value";
|
||||
static const char *MODE_UNKNOWN_STR = "unknown";
|
||||
|
||||
struct ICARUS_INFO {
|
||||
int intinfo;
|
||||
|
||||
// time to calculate the golden_ob
|
||||
uint64_t golden_hashes;
|
||||
struct timeval golden_tv;
|
||||
@ -184,6 +187,8 @@ struct ICARUS_INFO {
|
||||
struct ICARUS_HISTORY history[INFO_HISTORY+1];
|
||||
uint32_t min_data_count;
|
||||
|
||||
int timeout;
|
||||
|
||||
// seconds per Hash
|
||||
double Hs;
|
||||
// ms til we abort
|
||||
@ -233,8 +238,6 @@ struct ICARUS_INFO {
|
||||
//
|
||||
static int option_offset = -1;
|
||||
|
||||
struct device_drv icarus_drv;
|
||||
|
||||
/*
|
||||
#define ICA_BUFSIZ (0x200)
|
||||
|
||||
@ -277,7 +280,7 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
|
||||
usb_set_cps(icarus, baud / 10);
|
||||
usb_enable_cps(icarus);
|
||||
|
||||
interface = usb_interface(icarus);
|
||||
interface = _usb_interface(icarus, info->intinfo);
|
||||
ident = usb_ident(icarus);
|
||||
|
||||
switch (ident) {
|
||||
@ -287,9 +290,6 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
|
||||
case IDENT_CMR2:
|
||||
usb_set_pps(icarus, BLT_PREF_PACKET);
|
||||
|
||||
if (ident == IDENT_CMR2) // Chip hack
|
||||
interface++;
|
||||
|
||||
// Reset
|
||||
transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET,
|
||||
interface, C_RESET);
|
||||
@ -298,7 +298,7 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
|
||||
return;
|
||||
|
||||
// Latency
|
||||
usb_ftdi_set_latency(icarus);
|
||||
_usb_ftdi_set_latency(icarus, info->intinfo);
|
||||
|
||||
if (icarus->usbinfo.nodev)
|
||||
return;
|
||||
@ -434,9 +434,10 @@ static void rev(unsigned char *s, size_t l)
|
||||
|
||||
static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct timeval *tv_start, struct timeval *tv_finish, struct thr_info *thr, int read_time)
|
||||
{
|
||||
struct ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data);
|
||||
struct timeval read_start, read_finish;
|
||||
int err, amt;
|
||||
int rc = 0;
|
||||
int rc = 0, delay;
|
||||
int read_amount = ICARUS_READ_SIZE;
|
||||
bool first = true;
|
||||
|
||||
@ -446,7 +447,9 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
|
||||
return ICA_NONCE_ERROR;
|
||||
|
||||
cgtime(&read_start);
|
||||
err = usb_read_timeout(icarus, (char *)buf, read_amount, &amt, ICARUS_WAIT_TIMEOUT, C_GETRESULTS);
|
||||
err = usb_read_ii_timeout(icarus, info->intinfo,
|
||||
(char *)buf, read_amount, &amt,
|
||||
info->timeout, C_GETRESULTS);
|
||||
cgtime(&read_finish);
|
||||
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
|
||||
applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)",
|
||||
@ -471,10 +474,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
|
||||
}
|
||||
|
||||
if (thr && thr->work_restart) {
|
||||
if (opt_debug) {
|
||||
applog(LOG_DEBUG,
|
||||
"Icarus Read: Work restart at %d ms", rc);
|
||||
}
|
||||
applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
|
||||
return ICA_NONCE_RESTART;
|
||||
}
|
||||
|
||||
@ -483,6 +483,18 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
|
||||
read_amount -= amt;
|
||||
first = false;
|
||||
}
|
||||
|
||||
if (info->timeout < ICARUS_WAIT_TIMEOUT) {
|
||||
delay = ICARUS_WAIT_TIMEOUT - rc;
|
||||
if (delay > 0) {
|
||||
cgsleep_ms(delay);
|
||||
|
||||
if (thr && thr->work_restart) {
|
||||
applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
|
||||
return ICA_NONCE_RESTART;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -796,6 +808,7 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
|
||||
int baud, uninitialised_var(work_division), uninitialised_var(fpga_count);
|
||||
struct cgpu_info *icarus;
|
||||
int ret, err, amount, tries;
|
||||
enum sub_ident ident;
|
||||
bool ok;
|
||||
|
||||
icarus = usb_alloc_cgpu(&icarus_drv, 1);
|
||||
@ -814,6 +827,23 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
|
||||
quit(1, "Failed to malloc ICARUS_INFO");
|
||||
icarus->device_data = (void *)info;
|
||||
|
||||
ident = usb_ident(icarus);
|
||||
switch (ident) {
|
||||
case IDENT_ICA:
|
||||
case IDENT_BLT:
|
||||
case IDENT_LLT:
|
||||
case IDENT_AMU:
|
||||
case IDENT_CMR1:
|
||||
info->timeout = ICARUS_WAIT_TIMEOUT;
|
||||
break;
|
||||
case IDENT_CMR2:
|
||||
info->timeout = ICARUS_CMR2_TIMEOUT;
|
||||
break;
|
||||
default:
|
||||
quit(1, "%s icarus_detect_one() invalid %s ident=%d",
|
||||
icarus->drv->dname, icarus->drv->dname, ident);
|
||||
}
|
||||
|
||||
tries = 2;
|
||||
ok = false;
|
||||
while (!ok && tries-- > 0) {
|
||||
@ -879,7 +909,7 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
|
||||
struct cgpu_info *cgtmp;
|
||||
struct ICARUS_INFO *intmp;
|
||||
|
||||
cgtmp = usb_init_intinfo(icarus, i);
|
||||
cgtmp = usb_copy_cgpu(icarus);
|
||||
if (!cgtmp) {
|
||||
applog(LOG_ERR, "%s%d: Init failed initinfo %d",
|
||||
icarus->drv->name, icarus->device_id, i);
|
||||
@ -888,13 +918,6 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
|
||||
|
||||
cgtmp->usbinfo.usbstat = USB_NOSTAT;
|
||||
|
||||
if (!add_cgpu(cgtmp)) {
|
||||
usb_uninit(cgtmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
update_usb_stats(cgtmp);
|
||||
|
||||
intmp = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO));
|
||||
if (unlikely(!intmp))
|
||||
quit(1, "Failed2 to malloc ICARUS_INFO");
|
||||
@ -903,6 +926,18 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
|
||||
|
||||
// Initialise everything to match
|
||||
memcpy(intmp, info, sizeof(struct ICARUS_INFO));
|
||||
|
||||
intmp->intinfo = i;
|
||||
|
||||
icarus_initialise(cgtmp, baud);
|
||||
|
||||
if (!add_cgpu(cgtmp)) {
|
||||
usb_uninit(cgtmp);
|
||||
free(intmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
update_usb_stats(cgtmp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -921,7 +956,7 @@ shin:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void icarus_detect()
|
||||
static void icarus_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&icarus_drv, icarus_detect_one);
|
||||
}
|
||||
@ -976,7 +1011,7 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
|
||||
// We only want results for the work we are about to send
|
||||
usb_buffer_clear(icarus);
|
||||
|
||||
err = usb_write(icarus, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK);
|
||||
err = usb_write_ii(icarus, info->intinfo, (char *)ob_bin, sizeof(ob_bin), &amount, C_SENDWORK);
|
||||
if (err < 0 || amount != sizeof(ob_bin)) {
|
||||
applog(LOG_ERR, "%s%i: Comms error (werr=%d amt=%d)",
|
||||
icarus->drv->name, icarus->device_id, err, amount);
|
||||
@ -1014,12 +1049,10 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
|
||||
if (unlikely(estimate_hashes > 0xffffffff))
|
||||
estimate_hashes = 0xffffffff;
|
||||
|
||||
if (opt_debug) {
|
||||
applog(LOG_DEBUG, "%s%d: no nonce = 0x%08lX hashes (%ld.%06lds)",
|
||||
icarus->drv->name, icarus->device_id,
|
||||
(long unsigned int)estimate_hashes,
|
||||
elapsed.tv_sec, elapsed.tv_usec);
|
||||
}
|
||||
applog(LOG_DEBUG, "%s%d: no nonce = 0x%08lX hashes (%ld.%06lds)",
|
||||
icarus->drv->name, icarus->device_id,
|
||||
(long unsigned int)estimate_hashes,
|
||||
elapsed.tv_sec, elapsed.tv_usec);
|
||||
|
||||
return estimate_hashes;
|
||||
}
|
||||
@ -1051,12 +1084,10 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
|
||||
if (opt_debug || info->do_icarus_timing)
|
||||
timersub(&tv_finish, &tv_start, &elapsed);
|
||||
|
||||
if (opt_debug) {
|
||||
applog(LOG_DEBUG, "%s%d: nonce = 0x%08x = 0x%08lX hashes (%ld.%06lds)",
|
||||
icarus->drv->name, icarus->device_id,
|
||||
nonce, (long unsigned int)hash_count,
|
||||
elapsed.tv_sec, elapsed.tv_usec);
|
||||
}
|
||||
applog(LOG_DEBUG, "%s%d: nonce = 0x%08x = 0x%08lX hashes (%ld.%06lds)",
|
||||
icarus->drv->name, icarus->device_id,
|
||||
nonce, (long unsigned int)hash_count,
|
||||
elapsed.tv_sec, elapsed.tv_usec);
|
||||
|
||||
// Ignore possible end condition values ... and hw errors
|
||||
// TODO: set limitations on calculated values depending on the device
|
||||
@ -1203,7 +1234,7 @@ static void icarus_shutdown(__maybe_unused struct thr_info *thr)
|
||||
}
|
||||
|
||||
struct device_drv icarus_drv = {
|
||||
.drv_id = DRIVER_ICARUS,
|
||||
.drv_id = DRIVER_icarus,
|
||||
.dname = "Icarus",
|
||||
.name = "ICA",
|
||||
.drv_detect = icarus_detect,
|
||||
|
@ -87,8 +87,6 @@
|
||||
// Limit when reducing shares_to_good
|
||||
#define MODMINER_MIN_BACK 12
|
||||
|
||||
struct device_drv modminer_drv;
|
||||
|
||||
// 45 noops sent when detecting, in case the device was left in "start job" reading
|
||||
static const char NOOP[] = MODMINER_PING "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
|
||||
|
||||
@ -239,7 +237,7 @@ shin:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void modminer_detect()
|
||||
static void modminer_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
usb_detect(&modminer_drv, modminer_detect_one);
|
||||
}
|
||||
@ -1132,7 +1130,7 @@ static char *modminer_set_device(struct cgpu_info *modminer, char *option, char
|
||||
}
|
||||
|
||||
struct device_drv modminer_drv = {
|
||||
.drv_id = DRIVER_MODMINER,
|
||||
.drv_id = DRIVER_modminer,
|
||||
.dname = "ModMiner",
|
||||
.name = "MMQ",
|
||||
.drv_detect = modminer_detect,
|
||||
|
@ -56,10 +56,6 @@ extern void decay_time(double *f, double fadd);
|
||||
|
||||
/**********************************************/
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
struct device_drv opencl_drv;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ADL
|
||||
extern float gpu_temp(int gpu);
|
||||
extern int gpu_fanspeed(int gpu);
|
||||
@ -585,7 +581,7 @@ char *set_intensity(char *arg)
|
||||
void print_ndevs(int *ndevs)
|
||||
{
|
||||
opt_log_output = true;
|
||||
opencl_drv.drv_detect();
|
||||
opencl_drv.drv_detect(false);
|
||||
clear_adl(*ndevs);
|
||||
applog(LOG_INFO, "%i GPU devices max detected", *ndevs);
|
||||
}
|
||||
@ -753,7 +749,7 @@ retry:
|
||||
for (i = 0; i < mining_threads; ++i) {
|
||||
thr = get_thread(i);
|
||||
cgpu = thr->cgpu;
|
||||
if (cgpu->drv->drv_id != DRIVER_OPENCL)
|
||||
if (cgpu->drv->drv_id != DRIVER_opencl)
|
||||
continue;
|
||||
if (dev_from_id(i) != selected)
|
||||
continue;
|
||||
@ -1148,7 +1144,7 @@ select_cgpu:
|
||||
for (thr_id = 0; thr_id < mining_threads; ++thr_id) {
|
||||
thr = get_thread(thr_id);
|
||||
cgpu = thr->cgpu;
|
||||
if (cgpu->drv->drv_id != DRIVER_OPENCL)
|
||||
if (cgpu->drv->drv_id != DRIVER_opencl)
|
||||
continue;
|
||||
if (dev_from_id(thr_id) != gpu)
|
||||
continue;
|
||||
@ -1173,7 +1169,7 @@ select_cgpu:
|
||||
|
||||
thr = get_thread(thr_id);
|
||||
cgpu = thr->cgpu;
|
||||
if (cgpu->drv->drv_id != DRIVER_OPENCL)
|
||||
if (cgpu->drv->drv_id != DRIVER_opencl)
|
||||
continue;
|
||||
if (dev_from_id(thr_id) != gpu)
|
||||
continue;
|
||||
@ -1210,7 +1206,7 @@ select_cgpu:
|
||||
for (thr_id = 0; thr_id < mining_threads; ++thr_id) {
|
||||
thr = get_thread(thr_id);
|
||||
cgpu = thr->cgpu;
|
||||
if (cgpu->drv->drv_id != DRIVER_OPENCL)
|
||||
if (cgpu->drv->drv_id != DRIVER_opencl)
|
||||
continue;
|
||||
if (dev_from_id(thr_id) != gpu)
|
||||
continue;
|
||||
@ -1231,10 +1227,12 @@ void *reinit_gpu(__maybe_unused void *userdata)
|
||||
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
static void opencl_detect()
|
||||
static void opencl_detect(bool hotplug)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (opt_nogpu || hotplug)
|
||||
return;
|
||||
nDevs = clDevicesNum();
|
||||
if (nDevs < 0) {
|
||||
applog(LOG_ERR, "clDevicesNum returned error, no GPUs usable");
|
||||
@ -1575,7 +1573,7 @@ static void opencl_thread_shutdown(struct thr_info *thr)
|
||||
}
|
||||
|
||||
struct device_drv opencl_drv = {
|
||||
.drv_id = DRIVER_OPENCL,
|
||||
.drv_id = DRIVER_opencl,
|
||||
.dname = "opencl",
|
||||
.name = "GPU",
|
||||
.drv_detect = opencl_detect,
|
||||
|
@ -31,8 +31,6 @@
|
||||
|
||||
#define GOLDEN_BACKLOG 5
|
||||
|
||||
struct device_drv ztex_drv;
|
||||
|
||||
// Forward declarations
|
||||
static void ztex_disable(struct thr_info* thr);
|
||||
static bool ztex_prepare(struct thr_info *thr);
|
||||
@ -54,7 +52,7 @@ static void ztex_releaseFpga(struct libztex_device* ztex)
|
||||
}
|
||||
}
|
||||
|
||||
static void ztex_detect(void)
|
||||
static void ztex_detect(bool __maybe_unused hotplug)
|
||||
{
|
||||
int cnt;
|
||||
int i,j;
|
||||
@ -413,7 +411,7 @@ static void ztex_disable(struct thr_info *thr)
|
||||
}
|
||||
|
||||
struct device_drv ztex_drv = {
|
||||
.drv_id = DRIVER_ZTEX,
|
||||
.drv_id = DRIVER_ztex,
|
||||
.dname = "ztex",
|
||||
.name = "ZTX",
|
||||
.drv_detect = ztex_detect,
|
||||
|
56
miner.h
56
miner.h
@ -230,18 +230,39 @@ static inline int fsync (int fd)
|
||||
#define MIN(x, y) ((x) > (y) ? (y) : (x))
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
/* Put avalon last to make it the last device it tries to detect to prevent it
|
||||
* trying to claim same chip but different devices. Adding a device here will
|
||||
* update all macros in the code that use the *_PARSE_COMMANDS macros for each
|
||||
* listed driver. */
|
||||
#define FPGA_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \
|
||||
DRIVER_ADD_COMMAND(bitforce) \
|
||||
DRIVER_ADD_COMMAND(icarus) \
|
||||
DRIVER_ADD_COMMAND(modminer) \
|
||||
DRIVER_ADD_COMMAND(ztex)
|
||||
|
||||
#define ASIC_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \
|
||||
DRIVER_ADD_COMMAND(bflsc) \
|
||||
DRIVER_ADD_COMMAND(bitfury) \
|
||||
DRIVER_ADD_COMMAND(hashfast) \
|
||||
DRIVER_ADD_COMMAND(avalon)
|
||||
|
||||
#define DRIVER_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \
|
||||
DRIVER_ADD_COMMAND(opencl) \
|
||||
FPGA_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \
|
||||
ASIC_PARSE_COMMANDS(DRIVER_ADD_COMMAND)
|
||||
|
||||
#define DRIVER_ENUM(X) DRIVER_##X,
|
||||
#define DRIVER_PROTOTYPE(X) struct device_drv X##_drv;
|
||||
|
||||
/* Create drv_driver enum from DRIVER_PARSE_COMMANDS macro */
|
||||
enum drv_driver {
|
||||
DRIVER_OPENCL = 0,
|
||||
DRIVER_ICARUS,
|
||||
DRIVER_BITFORCE,
|
||||
DRIVER_MODMINER,
|
||||
DRIVER_ZTEX,
|
||||
DRIVER_BFLSC,
|
||||
DRIVER_AVALON,
|
||||
DRIVER_HASHFAST,
|
||||
DRIVER_PARSE_COMMANDS(DRIVER_ENUM)
|
||||
DRIVER_MAX
|
||||
};
|
||||
|
||||
/* Use DRIVER_PARSE_COMMANDS to generate extern device_drv prototypes */
|
||||
DRIVER_PARSE_COMMANDS(DRIVER_PROTOTYPE)
|
||||
|
||||
enum alive {
|
||||
LIFE_WELL,
|
||||
LIFE_SICK,
|
||||
@ -318,7 +339,7 @@ struct device_drv {
|
||||
char *name;
|
||||
|
||||
// DRV-global functions
|
||||
void (*drv_detect)();
|
||||
void (*drv_detect)(bool);
|
||||
|
||||
// Device-specific functions
|
||||
void (*reinit_device)(struct cgpu_info *);
|
||||
@ -823,7 +844,7 @@ static inline void cglock_init(cglock_t *lock)
|
||||
rwlock_init(&lock->rwlock);
|
||||
}
|
||||
|
||||
/* Read lock variant of cglock */
|
||||
/* Read lock variant of cglock. Cannot be promoted. */
|
||||
static inline void cg_rlock(cglock_t *lock)
|
||||
{
|
||||
mutex_lock(&lock->mutex);
|
||||
@ -831,7 +852,8 @@ static inline void cg_rlock(cglock_t *lock)
|
||||
mutex_unlock_noyield(&lock->mutex);
|
||||
}
|
||||
|
||||
/* Intermediate variant of cglock */
|
||||
/* Intermediate variant of cglock - behaves as a read lock but can be promoted
|
||||
* to a write lock or demoted to read lock. */
|
||||
static inline void cg_ilock(cglock_t *lock)
|
||||
{
|
||||
mutex_lock(&lock->mutex);
|
||||
@ -858,6 +880,12 @@ static inline void cg_dwlock(cglock_t *lock)
|
||||
mutex_unlock_noyield(&lock->mutex);
|
||||
}
|
||||
|
||||
/* Demote a write variant to an intermediate variant */
|
||||
static inline void cg_dwilock(cglock_t *lock)
|
||||
{
|
||||
wr_unlock(&lock->rwlock);
|
||||
}
|
||||
|
||||
/* Downgrade intermediate variant to a read lock */
|
||||
static inline void cg_dlock(cglock_t *lock)
|
||||
{
|
||||
@ -872,7 +900,7 @@ static inline void cg_runlock(cglock_t *lock)
|
||||
|
||||
static inline void cg_wunlock(cglock_t *lock)
|
||||
{
|
||||
wr_unlock(&lock->rwlock);
|
||||
wr_unlock_noyield(&lock->rwlock);
|
||||
mutex_unlock(&lock->mutex);
|
||||
}
|
||||
|
||||
@ -903,6 +931,7 @@ extern bool opt_api_listen;
|
||||
extern bool opt_api_network;
|
||||
extern bool opt_delaynet;
|
||||
extern bool opt_restart;
|
||||
extern bool opt_nogpu;
|
||||
extern char *opt_icarus_options;
|
||||
extern char *opt_icarus_timing;
|
||||
extern bool opt_worktime;
|
||||
@ -1263,6 +1292,7 @@ struct work {
|
||||
#endif
|
||||
double device_diff;
|
||||
uint64_t share_diff;
|
||||
unsigned char hash2[32];
|
||||
|
||||
int rolls;
|
||||
|
||||
@ -1356,6 +1386,8 @@ struct modminer_fpga_state {
|
||||
|
||||
extern void get_datestamp(char *, size_t, struct timeval *);
|
||||
extern void inc_hw_errors(struct thr_info *thr);
|
||||
extern bool test_nonce(struct work *work, uint32_t nonce);
|
||||
extern void submit_tested_work(struct thr_info *thr, struct work *work);
|
||||
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
||||
extern struct work *get_queued(struct cgpu_info *cgpu);
|
||||
extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
|
||||
|
681
usbutils.c
681
usbutils.c
File diff suppressed because it is too large
Load Diff
92
usbutils.h
92
usbutils.h
@ -109,6 +109,9 @@
|
||||
// Use the device defined timeout
|
||||
#define DEVTIMEOUT 0
|
||||
|
||||
// The default intinfo structure used is the first one
|
||||
#define DEFAULT_INTINFO 0
|
||||
|
||||
// For endpoints defined in usb_find_devices.intinfos.epinfos,
|
||||
// the first two must be the default IN and OUT and both must always exist
|
||||
#define DEFAULT_EP_IN 0
|
||||
@ -118,11 +121,14 @@ struct usb_epinfo {
|
||||
uint8_t att;
|
||||
uint16_t size;
|
||||
unsigned char ep;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint16_t PrefPacketSize;
|
||||
bool found;
|
||||
};
|
||||
|
||||
struct usb_intinfo {
|
||||
int interface;
|
||||
int ctrl_transfer;
|
||||
int epinfo_count;
|
||||
struct usb_epinfo *epinfos;
|
||||
};
|
||||
@ -134,6 +140,7 @@ enum sub_ident {
|
||||
IDENT_BAS,
|
||||
IDENT_BAM,
|
||||
IDENT_BFL,
|
||||
IDENT_BFU,
|
||||
IDENT_MMQ,
|
||||
IDENT_AVA,
|
||||
IDENT_BTB,
|
||||
@ -157,9 +164,7 @@ struct usb_find_devices {
|
||||
char *iProduct;
|
||||
int config;
|
||||
unsigned int timeout;
|
||||
uint16_t wMaxPacketSize;
|
||||
uint16_t latency;
|
||||
int which_intinfo;
|
||||
int intinfo_count;
|
||||
struct usb_intinfo *intinfos;
|
||||
};
|
||||
@ -193,7 +198,6 @@ struct cg_usb_device {
|
||||
char *buffer;
|
||||
uint32_t bufsiz;
|
||||
uint32_t bufamt;
|
||||
uint16_t PrefPacketSize;
|
||||
cgtimer_t cgt_last_write;
|
||||
size_t last_write_siz;
|
||||
};
|
||||
@ -234,7 +238,7 @@ struct cg_usb_info {
|
||||
* that uses the lock - however, all usbutils code MUST use it
|
||||
* to avoid devices disappearing while in use by multiple threads
|
||||
*/
|
||||
pthread_rwlock_t *devlock;
|
||||
pthread_mutex_t *devlock;
|
||||
|
||||
time_t last_pipe;
|
||||
uint64_t pipe_count;
|
||||
@ -258,7 +262,10 @@ struct cg_usb_info {
|
||||
struct cg_usb_tmo usb_tmo[USB_TMOS];
|
||||
};
|
||||
|
||||
#define USB_PARSE_COMMANDS \
|
||||
#define ENUMERATION(a,b) a,
|
||||
#define JUMPTABLE(a,b) b,
|
||||
|
||||
#define USB_PARSE_COMMANDS(USB_ADD_COMMAND) \
|
||||
USB_ADD_COMMAND(C_REJECTED, "RejectedNoDevice") \
|
||||
USB_ADD_COMMAND(C_PING, "Ping") \
|
||||
USB_ADD_COMMAND(C_CLEAR, "Clear") \
|
||||
@ -322,6 +329,20 @@ struct cg_usb_info {
|
||||
USB_ADD_COMMAND(C_ENABLE_UART, "EnableUART") \
|
||||
USB_ADD_COMMAND(C_BB_SET_VOLTAGE, "SetCoreVoltage") \
|
||||
USB_ADD_COMMAND(C_BB_GET_VOLTAGE, "GetCoreVoltage") \
|
||||
USB_ADD_COMMAND(C_BF1_RESET, "BF1Reset") \
|
||||
USB_ADD_COMMAND(C_BF1_OPEN, "BF1Open") \
|
||||
USB_ADD_COMMAND(C_BF1_INIT, "BF1Init") \
|
||||
USB_ADD_COMMAND(C_BF1_CLOSE, "BF1Close") \
|
||||
USB_ADD_COMMAND(C_BF1_REQINFO, "BF1RequestInfo") \
|
||||
USB_ADD_COMMAND(C_BF1_GETINFO, "BF1GetInfo") \
|
||||
USB_ADD_COMMAND(C_BF1_REQRESET, "BF1RequestReset") \
|
||||
USB_ADD_COMMAND(C_BF1_GETRESET, "BF1GetReset") \
|
||||
USB_ADD_COMMAND(C_BF1_REQWORK, "BF1RequestWork") \
|
||||
USB_ADD_COMMAND(C_BF1_GETWORK, "BF1GetWork") \
|
||||
USB_ADD_COMMAND(C_BF1_GETRES, "BF1GetResults") \
|
||||
USB_ADD_COMMAND(C_BF1_FLUSH, "BF1Flush") \
|
||||
USB_ADD_COMMAND(C_BF1_IFLUSH, "BF1InterruptFlush") \
|
||||
USB_ADD_COMMAND(C_BF1_IDENTIFY, "BF1Identify") \
|
||||
USB_ADD_COMMAND(C_HF_RESET, "HFReset") \
|
||||
USB_ADD_COMMAND(C_HF_PLL_CONFIG, "HFPLLConfig") \
|
||||
USB_ADD_COMMAND(C_HF_ADDRESS, "HFAddress") \
|
||||
@ -335,12 +356,10 @@ struct cg_usb_info {
|
||||
USB_ADD_COMMAND(C_HF_CLOCKGATE, "HFClockGate")
|
||||
|
||||
/* Create usb_cmds enum from USB_PARSE_COMMANDS macro */
|
||||
#define USB_ADD_COMMAND(X, Y) X,
|
||||
enum usb_cmds {
|
||||
USB_PARSE_COMMANDS
|
||||
USB_PARSE_COMMANDS(ENUMERATION)
|
||||
C_MAX
|
||||
};
|
||||
#undef USB_ADD_COMMAND
|
||||
|
||||
struct device_drv;
|
||||
struct cgpu_info;
|
||||
@ -353,17 +372,17 @@ struct cgpu_info *usb_alloc_cgpu(struct device_drv *drv, int threads);
|
||||
struct cgpu_info *usb_free_cgpu_devlock(struct cgpu_info *cgpu, bool free_devlock);
|
||||
#define usb_free_cgpu(cgpu) usb_free_cgpu_devlock(cgpu, true)
|
||||
void usb_uninit(struct cgpu_info *cgpu);
|
||||
struct cgpu_info *usb_init_intinfo(struct cgpu_info *orig, int intinfo);
|
||||
bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found);
|
||||
void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *));
|
||||
struct api_data *api_usb_stats(int *count);
|
||||
void update_usb_stats(struct cgpu_info *cgpu);
|
||||
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce);
|
||||
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
|
||||
int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce);
|
||||
int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds);
|
||||
int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd);
|
||||
int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, enum usb_cmds cmd);
|
||||
int usb_ftdi_cts(struct cgpu_info *cgpu);
|
||||
int usb_ftdi_set_latency(struct cgpu_info *cgpu);
|
||||
int _usb_ftdi_set_latency(struct cgpu_info *cgpu, int intinfo);
|
||||
#define usb_ftdi_set_latency(_cgpu) _usb_ftdi_set_latency(_cgpu, DEFAULT_INTINFO)
|
||||
void usb_buffer_enable(struct cgpu_info *cgpu);
|
||||
void usb_buffer_disable(struct cgpu_info *cgpu);
|
||||
void usb_buffer_clear(struct cgpu_info *cgpu);
|
||||
@ -371,55 +390,72 @@ uint32_t usb_buffer_size(struct cgpu_info *cgpu);
|
||||
void usb_set_cps(struct cgpu_info *cgpu, int cps);
|
||||
void usb_enable_cps(struct cgpu_info *cgpu);
|
||||
void usb_disable_cps(struct cgpu_info *cgpu);
|
||||
int usb_interface(struct cgpu_info *cgpu);
|
||||
int _usb_interface(struct cgpu_info *cgpu, int intinfo);
|
||||
#define usb_interface(_cgpu) _usb_interface(_cgpu, DEFAULT_INTINFO)
|
||||
enum sub_ident usb_ident(struct cgpu_info *cgpu);
|
||||
void usb_set_pps(struct cgpu_info *cgpu, uint16_t PrefPacketSize);
|
||||
void _usb_set_pps(struct cgpu_info *cgpu, int intinfo, int epinfo, uint16_t PrefPacketSize);
|
||||
#define usb_set_pps(_cgpu, _pps) _usb_set_pps(_cgpu, -1, -1, _pps)
|
||||
void usb_set_dev_start(struct cgpu_info *cgpu);
|
||||
void usb_cleanup();
|
||||
void usb_initialise();
|
||||
void *usb_resource_thread(void *userdata);
|
||||
|
||||
#define usb_read(cgpu, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
||||
|
||||
#define usb_read_ii(cgpu, intinfo, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
||||
|
||||
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true)
|
||||
|
||||
#define usb_read_ii_once(cgpu, intinfo, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true)
|
||||
|
||||
#define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true)
|
||||
|
||||
#define usb_read_ii_once_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true)
|
||||
|
||||
#define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "\n", cmd, false)
|
||||
|
||||
#define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "\n", cmd, false)
|
||||
|
||||
#define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, "OK\n", cmd, false)
|
||||
|
||||
#define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, "OK\n", cmd, false)
|
||||
|
||||
#define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \
|
||||
_usb_read(cgpu, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
||||
|
||||
#define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false)
|
||||
|
||||
#define usb_read_ii_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false)
|
||||
|
||||
#define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \
|
||||
_usb_read(cgpu, ep, buf, bufsiz, read, timeout, NULL, cmd, false)
|
||||
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, timeout, NULL, cmd, false)
|
||||
|
||||
#define usb_write(cgpu, buf, bufsiz, wrote, cmd) \
|
||||
_usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||
_usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||
|
||||
#define usb_write_ii(cgpu, intinfo, buf, bufsiz, wrote, cmd) \
|
||||
_usb_write(cgpu, intinfo, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||
|
||||
#define usb_write_ep(cgpu, ep, buf, bufsiz, wrote, cmd) \
|
||||
_usb_write(cgpu, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||
_usb_write(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||
|
||||
#define usb_write_timeout(cgpu, buf, bufsiz, wrote, timeout, cmd) \
|
||||
_usb_write(cgpu, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd)
|
||||
_usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, timeout, cmd)
|
||||
|
||||
#define usb_write_ep_timeout(cgpu, ep, buf, bufsiz, wrote, timeout, cmd) \
|
||||
_usb_write(cgpu, ep, buf, bufsiz, wrote, timeout, cmd)
|
||||
_usb_write(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, wrote, timeout, cmd)
|
||||
|
||||
#define usb_transfer(cgpu, typ, req, val, idx, cmd) \
|
||||
_usb_transfer(cgpu, typ, req, val, idx, NULL, 0, DEVTIMEOUT, cmd)
|
||||
|
6
util.c
6
util.c
@ -1074,6 +1074,12 @@ double us_tdiff(struct timeval *end, struct timeval *start)
|
||||
return end->tv_sec * 1000000 + end->tv_usec - start->tv_sec * 1000000 - start->tv_usec;
|
||||
}
|
||||
|
||||
/* Returns the milliseconds difference between end and start times */
|
||||
int ms_tdiff(struct timeval *end, struct timeval *start)
|
||||
{
|
||||
return end->tv_sec * 1000 + end->tv_usec / 1000 - start->tv_sec * 1000 - start->tv_usec / 1000;
|
||||
}
|
||||
|
||||
/* Returns the seconds difference between end and start times as a double */
|
||||
double tdiff(struct timeval *end, struct timeval *start)
|
||||
{
|
||||
|
1
util.h
1
util.h
@ -99,6 +99,7 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us);
|
||||
int cgtimer_to_ms(cgtimer_t *cgt);
|
||||
void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res);
|
||||
double us_tdiff(struct timeval *end, struct timeval *start);
|
||||
int ms_tdiff(struct timeval *end, struct timeval *start);
|
||||
double tdiff(struct timeval *end, struct timeval *start);
|
||||
bool stratum_send(struct pool *pool, char *s, ssize_t len);
|
||||
bool sock_full(struct pool *pool);
|
||||
|
Loading…
x
Reference in New Issue
Block a user