mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-13 00:07:55 +00:00
Merge branch 'master' into hashfast
This commit is contained in:
commit
f29f612182
53
cgminer.c
53
cgminer.c
@ -94,6 +94,7 @@ struct strategies strategies[] = {
|
|||||||
|
|
||||||
static char packagename[256];
|
static char packagename[256];
|
||||||
|
|
||||||
|
bool opt_work_update;
|
||||||
bool opt_protocol;
|
bool opt_protocol;
|
||||||
static bool opt_benchmark;
|
static bool opt_benchmark;
|
||||||
bool have_longpoll;
|
bool have_longpoll;
|
||||||
@ -1849,6 +1850,8 @@ static void update_gbt(struct pool *pool)
|
|||||||
applog(LOG_DEBUG, "Successfully retrieved and updated GBT from pool %u %s",
|
applog(LOG_DEBUG, "Successfully retrieved and updated GBT from pool %u %s",
|
||||||
pool->pool_no, pool->rpc_url);
|
pool->pool_no, pool->rpc_url);
|
||||||
cgtime(&pool->tv_idle);
|
cgtime(&pool->tv_idle);
|
||||||
|
if (pool == current_pool())
|
||||||
|
opt_work_update = true;
|
||||||
} else {
|
} else {
|
||||||
applog(LOG_DEBUG, "Successfully retrieved but FAILED to decipher GBT from pool %u %s",
|
applog(LOG_DEBUG, "Successfully retrieved but FAILED to decipher GBT from pool %u %s",
|
||||||
pool->pool_no, pool->rpc_url);
|
pool->pool_no, pool->rpc_url);
|
||||||
@ -1915,6 +1918,8 @@ static void gen_gbt_work(struct pool *pool, struct work *work)
|
|||||||
work->longpoll = false;
|
work->longpoll = false;
|
||||||
work->getwork_mode = GETWORK_MODE_GBT;
|
work->getwork_mode = GETWORK_MODE_GBT;
|
||||||
work->work_block = work_block;
|
work->work_block = work_block;
|
||||||
|
/* Nominally allow a driver to ntime roll 60 seconds */
|
||||||
|
work->drv_rolllimit = 60;
|
||||||
calc_diff(work, 0);
|
calc_diff(work, 0);
|
||||||
cgtime(&work->tv_staged);
|
cgtime(&work->tv_staged);
|
||||||
}
|
}
|
||||||
@ -3936,6 +3941,25 @@ static void restart_threads(void)
|
|||||||
mutex_lock(&restart_lock);
|
mutex_lock(&restart_lock);
|
||||||
pthread_cond_broadcast(&restart_cond);
|
pthread_cond_broadcast(&restart_cond);
|
||||||
mutex_unlock(&restart_lock);
|
mutex_unlock(&restart_lock);
|
||||||
|
|
||||||
|
#ifdef USE_USBUTILS
|
||||||
|
/* Cancels any cancellable usb transfers. Flagged as such it means they
|
||||||
|
* are usualy waiting on a read result and it's safe to abort the read
|
||||||
|
* early. */
|
||||||
|
cancel_usb_transfers();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void signal_work_update(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
applog(LOG_INFO, "Work update message received");
|
||||||
|
|
||||||
|
rd_lock(&mining_thr_lock);
|
||||||
|
for (i = 0; i < mining_threads; i++)
|
||||||
|
mining_thr[i]->work_update = true;
|
||||||
|
rd_unlock(&mining_thr_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_curblock(char *hexstr, unsigned char *hash)
|
static void set_curblock(char *hexstr, unsigned char *hash)
|
||||||
@ -5998,6 +6022,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
|
|||||||
work->longpoll = false;
|
work->longpoll = false;
|
||||||
work->getwork_mode = GETWORK_MODE_STRATUM;
|
work->getwork_mode = GETWORK_MODE_STRATUM;
|
||||||
work->work_block = work_block;
|
work->work_block = work_block;
|
||||||
|
/* Nominally allow a driver to ntime roll 60 seconds */
|
||||||
|
work->drv_rolllimit = 60;
|
||||||
calc_diff(work, work->sdiff);
|
calc_diff(work, work->sdiff);
|
||||||
|
|
||||||
cgtime(&work->tv_staged);
|
cgtime(&work->tv_staged);
|
||||||
@ -6502,7 +6528,7 @@ void hash_queued_work(struct thr_info *mythr)
|
|||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
int64_t hashes;
|
int64_t hashes;
|
||||||
|
|
||||||
mythr->work_restart = false;
|
mythr->work_restart = mythr->work_update = false;
|
||||||
|
|
||||||
fill_queue(mythr, cgpu, drv, thr_id);
|
fill_queue(mythr, cgpu, drv, thr_id);
|
||||||
|
|
||||||
@ -6532,7 +6558,8 @@ void hash_queued_work(struct thr_info *mythr)
|
|||||||
if (unlikely(mythr->work_restart)) {
|
if (unlikely(mythr->work_restart)) {
|
||||||
flush_queue(cgpu);
|
flush_queue(cgpu);
|
||||||
drv->flush_work(cgpu);
|
drv->flush_work(cgpu);
|
||||||
}
|
} else if (mythr->work_update)
|
||||||
|
drv->update_work(cgpu);
|
||||||
}
|
}
|
||||||
cgpu->deven = DEV_DISABLED;
|
cgpu->deven = DEV_DISABLED;
|
||||||
}
|
}
|
||||||
@ -6553,7 +6580,7 @@ void hash_driver_work(struct thr_info *mythr)
|
|||||||
struct timeval diff;
|
struct timeval diff;
|
||||||
int64_t hashes;
|
int64_t hashes;
|
||||||
|
|
||||||
mythr->work_restart = false;
|
mythr->work_restart = mythr->work_update = false;
|
||||||
|
|
||||||
hashes = drv->scanwork(mythr);
|
hashes = drv->scanwork(mythr);
|
||||||
|
|
||||||
@ -6580,6 +6607,8 @@ void hash_driver_work(struct thr_info *mythr)
|
|||||||
|
|
||||||
if (unlikely(mythr->work_restart))
|
if (unlikely(mythr->work_restart))
|
||||||
drv->flush_work(cgpu);
|
drv->flush_work(cgpu);
|
||||||
|
else if (mythr->work_update)
|
||||||
|
drv->update_work(cgpu);
|
||||||
}
|
}
|
||||||
cgpu->deven = DEV_DISABLED;
|
cgpu->deven = DEV_DISABLED;
|
||||||
}
|
}
|
||||||
@ -6608,8 +6637,6 @@ void *miner_thread(void *userdata)
|
|||||||
out:
|
out:
|
||||||
drv->thread_shutdown(mythr);
|
drv->thread_shutdown(mythr);
|
||||||
|
|
||||||
applog(LOG_ERR, "Thread %d failure, exiting", thr_id);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7560,6 +7587,7 @@ static void noop_detect(bool __maybe_unused hotplug)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
#define noop_flush_work noop_reinit_device
|
#define noop_flush_work noop_reinit_device
|
||||||
|
#define noop_update_work noop_reinit_device
|
||||||
#define noop_queue_full noop_get_stats
|
#define noop_queue_full noop_get_stats
|
||||||
|
|
||||||
/* Fill missing driver drv functions with noops */
|
/* Fill missing driver drv functions with noops */
|
||||||
@ -7593,6 +7621,8 @@ void fill_device_drv(struct device_drv *drv)
|
|||||||
drv->hash_work = &hash_sole_work;
|
drv->hash_work = &hash_sole_work;
|
||||||
if (!drv->flush_work)
|
if (!drv->flush_work)
|
||||||
drv->flush_work = &noop_flush_work;
|
drv->flush_work = &noop_flush_work;
|
||||||
|
if (!drv->update_work)
|
||||||
|
drv->update_work = &noop_update_work;
|
||||||
if (!drv->queue_full)
|
if (!drv->queue_full)
|
||||||
drv->queue_full = &noop_queue_full;
|
drv->queue_full = &noop_queue_full;
|
||||||
if (!drv->max_diff)
|
if (!drv->max_diff)
|
||||||
@ -7810,22 +7840,20 @@ static void probe_pools(void)
|
|||||||
static void *libusb_poll_thread(void __maybe_unused *arg)
|
static void *libusb_poll_thread(void __maybe_unused *arg)
|
||||||
{
|
{
|
||||||
struct timeval tv_end = {1, 0};
|
struct timeval tv_end = {1, 0};
|
||||||
bool inprogress = false;
|
|
||||||
|
|
||||||
RenameThread("usbpoll");
|
RenameThread("usbpoll");
|
||||||
|
|
||||||
while (usb_polling)
|
while (usb_polling)
|
||||||
libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
|
libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
|
||||||
|
|
||||||
|
/* Cancel any cancellable usb transfers */
|
||||||
|
cancel_usb_transfers();
|
||||||
|
|
||||||
/* Keep event handling going until there are no async transfers in
|
/* Keep event handling going until there are no async transfers in
|
||||||
* flight. */
|
* flight. */
|
||||||
do {
|
do {
|
||||||
libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
|
libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
|
||||||
|
} while (async_usb_transfers());
|
||||||
cg_rlock(&cgusb_fd_lock);
|
|
||||||
inprogress = !!cgusb_transfers;
|
|
||||||
cg_runlock(&cgusb_fd_lock);
|
|
||||||
} while (inprogress);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -8313,6 +8341,9 @@ begin_bench:
|
|||||||
bool lagging = false;
|
bool lagging = false;
|
||||||
struct work *work;
|
struct work *work;
|
||||||
|
|
||||||
|
if (opt_work_update)
|
||||||
|
signal_work_update();
|
||||||
|
opt_work_update = false;
|
||||||
cp = current_pool();
|
cp = current_pool();
|
||||||
|
|
||||||
/* If the primary pool is a getwork pool and cannot roll work,
|
/* If the primary pool is a getwork pool and cannot roll work,
|
||||||
|
@ -248,7 +248,7 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
|
|||||||
cgtime(&tv_now);
|
cgtime(&tv_now);
|
||||||
ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start);
|
ms_diff = 600 - ms_tdiff(&tv_now, &info->tv_start);
|
||||||
if (ms_diff > 0) {
|
if (ms_diff > 0) {
|
||||||
usb_read_timeout(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES);
|
usb_read_timeout_cancellable(bitfury, info->buf, 512, &amount, ms_diff, C_BF1_GETRES);
|
||||||
info->tot += amount;
|
info->tot += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ static int64_t bitfury_scanwork(struct thr_info *thr)
|
|||||||
ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start);
|
ms_diff = BF1WAIT - ms_tdiff(&tv_now, &info->tv_start);
|
||||||
if (unlikely(ms_diff < 10))
|
if (unlikely(ms_diff < 10))
|
||||||
ms_diff = 10;
|
ms_diff = 10;
|
||||||
usb_read_once_timeout(bitfury, info->buf + info->tot, BF1MSGSIZE,
|
usb_read_once_timeout_cancellable(bitfury, info->buf + info->tot, BF1MSGSIZE,
|
||||||
&amount, ms_diff, C_BF1_GETRES);
|
&amount, ms_diff, C_BF1_GETRES);
|
||||||
info->tot += amount;
|
info->tot += amount;
|
||||||
while (amount) {
|
while (amount) {
|
||||||
|
@ -471,70 +471,42 @@ static void rev(unsigned char *s, size_t l)
|
|||||||
#define ICA_NONCE_RESTART 1
|
#define ICA_NONCE_RESTART 1
|
||||||
#define ICA_NONCE_TIMEOUT 2
|
#define ICA_NONCE_TIMEOUT 2
|
||||||
|
|
||||||
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)
|
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 ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data);
|
||||||
struct timeval read_start, read_finish;
|
int err, amt, rc;
|
||||||
int err, amt;
|
|
||||||
int rc = 0, delay;
|
|
||||||
int read_amount = ICARUS_READ_SIZE;
|
|
||||||
bool first = true;
|
|
||||||
|
|
||||||
cgtime(tv_start);
|
|
||||||
while (true) {
|
|
||||||
if (icarus->usbinfo.nodev)
|
if (icarus->usbinfo.nodev)
|
||||||
return ICA_NONCE_ERROR;
|
return ICA_NONCE_ERROR;
|
||||||
|
|
||||||
cgtime(&read_start);
|
cgtime(tv_start);
|
||||||
err = usb_read_ii_timeout(icarus, info->intinfo,
|
err = usb_read_ii_timeout_cancellable(icarus, info->intinfo, (char *)buf,
|
||||||
(char *)buf, read_amount, &amt,
|
ICARUS_READ_SIZE, &amt, read_time,
|
||||||
info->timeout, C_GETRESULTS);
|
C_GETRESULTS);
|
||||||
cgtime(&read_finish);
|
cgtime(tv_finish);
|
||||||
|
|
||||||
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
|
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
|
||||||
applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)",
|
applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)", icarus->drv->name,
|
||||||
icarus->drv->name, icarus->device_id, err, amt);
|
icarus->device_id, err, amt);
|
||||||
dev_error(icarus, REASON_DEV_COMMS_ERROR);
|
dev_error(icarus, REASON_DEV_COMMS_ERROR);
|
||||||
return ICA_NONCE_ERROR;
|
return ICA_NONCE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first)
|
if (amt >= ICARUS_READ_SIZE)
|
||||||
copy_time(tv_finish, &read_finish);
|
|
||||||
|
|
||||||
if (amt >= read_amount)
|
|
||||||
return ICA_NONCE_OK;
|
return ICA_NONCE_OK;
|
||||||
|
|
||||||
rc = SECTOMS(tdiff(&read_finish, tv_start));
|
rc = SECTOMS(tdiff(tv_finish, tv_start));
|
||||||
if (rc >= read_time) {
|
if (thr && thr->work_restart) {
|
||||||
|
applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
|
||||||
|
return ICA_NONCE_RESTART;
|
||||||
|
}
|
||||||
|
|
||||||
if (amt > 0)
|
if (amt > 0)
|
||||||
applog(LOG_DEBUG, "Icarus Read: Timeout reading for %d ms", rc);
|
applog(LOG_DEBUG, "Icarus Read: Timeout reading for %d ms", rc);
|
||||||
else
|
else
|
||||||
applog(LOG_DEBUG, "Icarus Read: No data for %d ms", rc);
|
applog(LOG_DEBUG, "Icarus Read: No data for %d ms", rc);
|
||||||
return ICA_NONCE_TIMEOUT;
|
return ICA_NONCE_TIMEOUT;
|
||||||
}
|
|
||||||
|
|
||||||
if (thr && thr->work_restart) {
|
|
||||||
applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
|
|
||||||
return ICA_NONCE_RESTART;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (amt > 0) {
|
|
||||||
buf += amt;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *timing_mode_str(enum timing_mode timing_mode)
|
static const char *timing_mode_str(enum timing_mode timing_mode)
|
||||||
|
6
miner.h
6
miner.h
@ -364,7 +364,10 @@ struct device_drv {
|
|||||||
* the main loop that it should not add any further work to the table.
|
* the main loop that it should not add any further work to the table.
|
||||||
*/
|
*/
|
||||||
bool (*queue_full)(struct cgpu_info *);
|
bool (*queue_full)(struct cgpu_info *);
|
||||||
|
/* Tell the driver of a block change */
|
||||||
void (*flush_work)(struct cgpu_info *);
|
void (*flush_work)(struct cgpu_info *);
|
||||||
|
/* Tell the driver of an updated work template for eg. stratum */
|
||||||
|
void (*update_work)(struct cgpu_info *);
|
||||||
|
|
||||||
void (*hw_error)(struct thr_info *);
|
void (*hw_error)(struct thr_info *);
|
||||||
void (*thread_shutdown)(struct thr_info *);
|
void (*thread_shutdown)(struct thr_info *);
|
||||||
@ -612,6 +615,7 @@ struct thr_info {
|
|||||||
double rolling;
|
double rolling;
|
||||||
|
|
||||||
bool work_restart;
|
bool work_restart;
|
||||||
|
bool work_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct string_elist {
|
struct string_elist {
|
||||||
@ -990,6 +994,7 @@ struct pool;
|
|||||||
#define API_MCAST_CODE "FTW"
|
#define API_MCAST_CODE "FTW"
|
||||||
#define API_MCAST_ADDR "224.0.0.75"
|
#define API_MCAST_ADDR "224.0.0.75"
|
||||||
|
|
||||||
|
extern bool opt_work_update;
|
||||||
extern bool opt_protocol;
|
extern bool opt_protocol;
|
||||||
extern bool have_longpoll;
|
extern bool have_longpoll;
|
||||||
extern char *opt_kernel_path;
|
extern char *opt_kernel_path;
|
||||||
@ -1385,6 +1390,7 @@ struct work {
|
|||||||
unsigned char hash2[32];
|
unsigned char hash2[32];
|
||||||
|
|
||||||
int rolls;
|
int rolls;
|
||||||
|
int drv_rolllimit; /* How much the driver can roll ntime */
|
||||||
|
|
||||||
dev_blk_ctx blk;
|
dev_blk_ctx blk;
|
||||||
|
|
||||||
|
83
usbutils.c
83
usbutils.c
@ -95,9 +95,10 @@
|
|||||||
.epinfos = _epinfosy \
|
.epinfos = _epinfosy \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep a global counter of how many async transfers are in place to avoid
|
/* Linked list of all async transfers in progress. Protected by cgusb_fd_lock.
|
||||||
* shutting down the usb polling thread while they exist. */
|
* This allows us to not stop the usb polling thread till all are complete, and
|
||||||
int cgusb_transfers;
|
* to find cancellable transfers. */
|
||||||
|
static struct list_head ut_list;
|
||||||
|
|
||||||
#ifdef USE_BFLSC
|
#ifdef USE_BFLSC
|
||||||
// N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1
|
// N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1
|
||||||
@ -2247,8 +2248,44 @@ static char *find_end(unsigned char *buf, unsigned char *ptr, int ptrlen, int to
|
|||||||
struct usb_transfer {
|
struct usb_transfer {
|
||||||
cgsem_t cgsem;
|
cgsem_t cgsem;
|
||||||
struct libusb_transfer *transfer;
|
struct libusb_transfer *transfer;
|
||||||
|
bool cancellable;
|
||||||
|
struct list_head list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool async_usb_transfers(void)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
cg_rlock(&cgusb_fd_lock);
|
||||||
|
ret = !list_empty(&ut_list);
|
||||||
|
cg_runlock(&cgusb_fd_lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cancellable transfers should only be labelled as such if it is safe for them
|
||||||
|
* to effectively mimic timing out early. This flag is usually used to signify
|
||||||
|
* a read is waiting on a non-critical response that takes a long time and the
|
||||||
|
* driver wishes it be aborted if work restart message has been sent. */
|
||||||
|
void cancel_usb_transfers(void)
|
||||||
|
{
|
||||||
|
struct usb_transfer *ut;
|
||||||
|
int cancellations = 0;
|
||||||
|
|
||||||
|
cg_wlock(&cgusb_fd_lock);
|
||||||
|
list_for_each_entry(ut, &ut_list, list) {
|
||||||
|
if (ut->cancellable) {
|
||||||
|
ut->cancellable = false;
|
||||||
|
libusb_cancel_transfer(ut->transfer);
|
||||||
|
cancellations++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cg_wunlock(&cgusb_fd_lock);
|
||||||
|
|
||||||
|
if (cancellations)
|
||||||
|
applog(LOG_DEBUG, "Cancelled %d USB transfers", cancellations);
|
||||||
|
}
|
||||||
|
|
||||||
static void init_usb_transfer(struct usb_transfer *ut)
|
static void init_usb_transfer(struct usb_transfer *ut)
|
||||||
{
|
{
|
||||||
cgsem_init(&ut->cgsem);
|
cgsem_init(&ut->cgsem);
|
||||||
@ -2256,22 +2293,24 @@ static void init_usb_transfer(struct usb_transfer *ut)
|
|||||||
if (unlikely(!ut->transfer))
|
if (unlikely(!ut->transfer))
|
||||||
quit(1, "Failed to libusb_alloc_transfer");
|
quit(1, "Failed to libusb_alloc_transfer");
|
||||||
ut->transfer->user_data = ut;
|
ut->transfer->user_data = ut;
|
||||||
|
ut->cancellable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void complete_usb_transfer(struct usb_transfer *ut)
|
static void complete_usb_transfer(struct usb_transfer *ut)
|
||||||
{
|
{
|
||||||
|
cg_wlock(&cgusb_fd_lock);
|
||||||
|
list_del(&ut->list);
|
||||||
|
cg_wunlock(&cgusb_fd_lock);
|
||||||
|
|
||||||
cgsem_destroy(&ut->cgsem);
|
cgsem_destroy(&ut->cgsem);
|
||||||
libusb_free_transfer(ut->transfer);
|
libusb_free_transfer(ut->transfer);
|
||||||
|
|
||||||
cg_wlock(&cgusb_fd_lock);
|
|
||||||
cgusb_transfers--;
|
|
||||||
cg_wunlock(&cgusb_fd_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer)
|
static void LIBUSB_CALL transfer_callback(struct libusb_transfer *transfer)
|
||||||
{
|
{
|
||||||
struct usb_transfer *ut = transfer->user_data;
|
struct usb_transfer *ut = transfer->user_data;
|
||||||
|
|
||||||
|
ut->cancellable = false;
|
||||||
cgsem_post(&ut->cgsem);
|
cgsem_post(&ut->cgsem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2326,13 +2365,18 @@ static int callback_wait(struct usb_transfer *ut, int *transferred, unsigned int
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_submit_transfer(struct libusb_transfer *transfer)
|
static int usb_submit_transfer(struct usb_transfer *ut, struct libusb_transfer *transfer,
|
||||||
|
bool cancellable)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&ut->list);
|
||||||
|
|
||||||
cg_wlock(&cgusb_fd_lock);
|
cg_wlock(&cgusb_fd_lock);
|
||||||
err = libusb_submit_transfer(transfer);
|
err = libusb_submit_transfer(transfer);
|
||||||
cgusb_transfers++;
|
if (likely(!err))
|
||||||
|
ut->cancellable = cancellable;
|
||||||
|
list_add(&ut->list, &ut_list);
|
||||||
cg_wunlock(&cgusb_fd_lock);
|
cg_wunlock(&cgusb_fd_lock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@ -2343,7 +2387,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
|
|||||||
int epinfo, unsigned char *data, int length,
|
int epinfo, unsigned char *data, int length,
|
||||||
int *transferred, unsigned int timeout,
|
int *transferred, unsigned int timeout,
|
||||||
struct cgpu_info *cgpu, __maybe_unused int mode,
|
struct cgpu_info *cgpu, __maybe_unused int mode,
|
||||||
enum usb_cmds cmd, __maybe_unused int seq)
|
enum usb_cmds cmd, __maybe_unused int seq, bool cancellable)
|
||||||
{
|
{
|
||||||
struct usb_epinfo *usb_epinfo;
|
struct usb_epinfo *usb_epinfo;
|
||||||
struct usb_transfer ut;
|
struct usb_transfer ut;
|
||||||
@ -2381,7 +2425,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
|
|||||||
libusb_fill_bulk_transfer(ut.transfer, dev_handle, endpoint, buf, length,
|
libusb_fill_bulk_transfer(ut.transfer, dev_handle, endpoint, buf, length,
|
||||||
transfer_callback, &ut, 0);
|
transfer_callback, &ut, 0);
|
||||||
STATS_TIMEVAL(&tv_start);
|
STATS_TIMEVAL(&tv_start);
|
||||||
err = usb_submit_transfer(ut.transfer);
|
err = usb_submit_transfer(&ut, ut.transfer, cancellable);
|
||||||
errn = errno;
|
errn = errno;
|
||||||
if (!err)
|
if (!err)
|
||||||
err = callback_wait(&ut, transferred, timeout);
|
err = callback_wait(&ut, transferred, timeout);
|
||||||
@ -2417,7 +2461,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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, bool cancellable)
|
||||||
{
|
{
|
||||||
struct cg_usb_device *usbdev;
|
struct cg_usb_device *usbdev;
|
||||||
bool ftdi;
|
bool ftdi;
|
||||||
@ -2500,7 +2544,8 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
|
|||||||
}
|
}
|
||||||
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
||||||
ptr, usbbufread, &got, timeout,
|
ptr, usbbufread, &got, timeout,
|
||||||
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1);
|
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1,
|
||||||
|
cancellable);
|
||||||
cgtime(&tv_finish);
|
cgtime(&tv_finish);
|
||||||
ptr[got] = '\0';
|
ptr[got] = '\0';
|
||||||
|
|
||||||
@ -2600,7 +2645,8 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
|
|||||||
}
|
}
|
||||||
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
||||||
ptr, usbbufread, &got, timeout,
|
ptr, usbbufread, &got, timeout,
|
||||||
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1);
|
cgpu, MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1,
|
||||||
|
cancellable);
|
||||||
cgtime(&tv_finish);
|
cgtime(&tv_finish);
|
||||||
ptr[got] = '\0';
|
ptr[got] = '\0';
|
||||||
|
|
||||||
@ -2749,7 +2795,8 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
|
|||||||
}
|
}
|
||||||
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
err = usb_bulk_transfer(usbdev->handle, intinfo, epinfo,
|
||||||
(unsigned char *)buf, bufsiz, &sent, timeout,
|
(unsigned char *)buf, bufsiz, &sent, timeout,
|
||||||
cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1);
|
cgpu, MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1,
|
||||||
|
false);
|
||||||
cgtime(&tv_finish);
|
cgtime(&tv_finish);
|
||||||
|
|
||||||
USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent);
|
USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent);
|
||||||
@ -2815,7 +2862,7 @@ static int usb_control_transfer(struct cgpu_info *cgpu, libusb_device_handle *de
|
|||||||
memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, buffer, wLength);
|
memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, buffer, wLength);
|
||||||
libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback,
|
libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback,
|
||||||
&ut, 0);
|
&ut, 0);
|
||||||
err = usb_submit_transfer(ut.transfer);
|
err = usb_submit_transfer(&ut, ut.transfer, false);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = callback_wait(&ut, &transferred, timeout);
|
err = callback_wait(&ut, &transferred, timeout);
|
||||||
if (err == LIBUSB_SUCCESS && transferred) {
|
if (err == LIBUSB_SUCCESS && transferred) {
|
||||||
@ -3320,12 +3367,14 @@ void usb_cleanup(void)
|
|||||||
drv_count[X##_drv.drv_id].limit = lim; \
|
drv_count[X##_drv.drv_id].limit = lim; \
|
||||||
found = true; \
|
found = true; \
|
||||||
}
|
}
|
||||||
void usb_initialise()
|
void usb_initialise(void)
|
||||||
{
|
{
|
||||||
char *fre, *ptr, *comma, *colon;
|
char *fre, *ptr, *comma, *colon;
|
||||||
int bus, dev, lim, i;
|
int bus, dev, lim, i;
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&ut_list);
|
||||||
|
|
||||||
for (i = 0; i < DRIVER_MAX; i++) {
|
for (i = 0; i < DRIVER_MAX; i++) {
|
||||||
drv_count[i].count = 0;
|
drv_count[i].count = 0;
|
||||||
drv_count[i].limit = 999999;
|
drv_count[i].limit = 999999;
|
||||||
|
46
usbutils.h
46
usbutils.h
@ -117,8 +117,6 @@
|
|||||||
#define DEFAULT_EP_IN 0
|
#define DEFAULT_EP_IN 0
|
||||||
#define DEFAULT_EP_OUT 1
|
#define DEFAULT_EP_OUT 1
|
||||||
|
|
||||||
int cgusb_transfers;
|
|
||||||
|
|
||||||
struct usb_epinfo {
|
struct usb_epinfo {
|
||||||
uint8_t att;
|
uint8_t att;
|
||||||
uint16_t size;
|
uint16_t size;
|
||||||
@ -376,6 +374,8 @@ enum usb_cmds {
|
|||||||
struct device_drv;
|
struct device_drv;
|
||||||
struct cgpu_info;
|
struct cgpu_info;
|
||||||
|
|
||||||
|
bool async_usb_transfers(void);
|
||||||
|
void cancel_usb_transfers(void);
|
||||||
void usb_all(int level);
|
void usb_all(int level);
|
||||||
const char *usb_cmdname(enum usb_cmds cmd);
|
const char *usb_cmdname(enum usb_cmds cmd);
|
||||||
void usb_applog(struct cgpu_info *bflsc, enum usb_cmds cmd, char *msg, int amount, int err);
|
void usb_applog(struct cgpu_info *bflsc, enum usb_cmds cmd, char *msg, int amount, int err);
|
||||||
@ -387,7 +387,7 @@ bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find
|
|||||||
void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *));
|
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);
|
struct api_data *api_usb_stats(int *count);
|
||||||
void update_usb_stats(struct cgpu_info *cgpu);
|
void update_usb_stats(struct cgpu_info *cgpu);
|
||||||
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_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, bool cancellable);
|
||||||
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_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(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_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);
|
||||||
@ -412,46 +412,58 @@ void usb_initialise();
|
|||||||
void *usb_resource_thread(void *userdata);
|
void *usb_resource_thread(void *userdata);
|
||||||
|
|
||||||
#define usb_read(cgpu, buf, bufsiz, read, cmd) \
|
#define usb_read(cgpu, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
|
#define usb_read_cancellable(cgpu, buf, bufsiz, read, cmd) \
|
||||||
|
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, true)
|
||||||
|
|
||||||
#define usb_read_ii(cgpu, intinfo, buf, bufsiz, read, cmd) \
|
#define usb_read_ii(cgpu, intinfo, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, false)
|
||||||
|
|
||||||
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
|
#define usb_read_once(cgpu, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
#define usb_read_ii_once(cgpu, intinfo, buf, bufsiz, read, cmd) \
|
#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)
|
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, true, false)
|
||||||
|
|
||||||
#define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
#define usb_read_once_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
|
#define usb_read_once_timeout_cancellable(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
|
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true, true)
|
||||||
|
|
||||||
#define usb_read_ii_once_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
|
#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)
|
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, true, false)
|
||||||
|
|
||||||
#define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
|
#define usb_read_nl(cgpu, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
#define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
#define usb_read_nl_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
#define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \
|
#define usb_read_ok(cgpu, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
#define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
#define usb_read_ok_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
#define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \
|
#define usb_read_ep(cgpu, ep, buf, bufsiz, read, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false)
|
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, DEVTIMEOUT, NULL, cmd, false, false)
|
||||||
|
|
||||||
#define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
#define usb_read_timeout(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, 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, false)
|
||||||
|
|
||||||
|
#define usb_read_timeout_cancellable(cgpu, buf, bufsiz, read, timeout, cmd) \
|
||||||
|
_usb_read(cgpu, DEFAULT_INTINFO, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false, true)
|
||||||
|
|
||||||
#define usb_read_ii_timeout(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
|
#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)
|
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false, false)
|
||||||
|
|
||||||
|
#define usb_read_ii_timeout_cancellable(cgpu, intinfo, buf, bufsiz, read, timeout, cmd) \
|
||||||
|
_usb_read(cgpu, intinfo, DEFAULT_EP_IN, buf, bufsiz, read, timeout, NULL, cmd, false, true)
|
||||||
|
|
||||||
#define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \
|
#define usb_read_ep_timeout(cgpu, ep, buf, bufsiz, read, timeout, cmd) \
|
||||||
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, timeout, NULL, cmd, false)
|
_usb_read(cgpu, DEFAULT_INTINFO, ep, buf, bufsiz, read, timeout, NULL, cmd, false, false)
|
||||||
|
|
||||||
#define usb_write(cgpu, buf, bufsiz, wrote, cmd) \
|
#define usb_write(cgpu, buf, bufsiz, wrote, cmd) \
|
||||||
_usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
_usb_write(cgpu, DEFAULT_INTINFO, DEFAULT_EP_OUT, buf, bufsiz, wrote, DEVTIMEOUT, cmd)
|
||||||
|
2
util.c
2
util.c
@ -1610,6 +1610,8 @@ static bool parse_notify(struct pool *pool, json_t *val)
|
|||||||
pool->getwork_requested++;
|
pool->getwork_requested++;
|
||||||
total_getworks++;
|
total_getworks++;
|
||||||
ret = true;
|
ret = true;
|
||||||
|
if (pool == current_pool())
|
||||||
|
opt_work_update = true;
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user