Browse Source

Merge branch 'master' into hashfast

nfactor-troky
Con Kolivas 11 years ago
parent
commit
f29f612182
  1. 53
      cgminer.c
  2. 6
      driver-bitfury.c
  3. 86
      driver-icarus.c
  4. 6
      miner.h
  5. 83
      usbutils.c
  6. 46
      usbutils.h
  7. 2
      util.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,

6
driver-bitfury.c

@ -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,8 +261,8 @@ 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) {
usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES); usb_read_once_timeout(bitfury, info->buf + info->tot, 512, &amount, 10, C_BF1_GETRES);

86
driver-icarus.c

@ -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); if (icarus->usbinfo.nodev)
while (true) { return ICA_NONCE_ERROR;
if (icarus->usbinfo.nodev)
return ICA_NONCE_ERROR;
cgtime(&read_start);
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)",
icarus->drv->name, icarus->device_id, err, amt);
dev_error(icarus, REASON_DEV_COMMS_ERROR);
return ICA_NONCE_ERROR;
}
if (first)
copy_time(tv_finish, &read_finish);
if (amt >= read_amount)
return ICA_NONCE_OK;
rc = SECTOMS(tdiff(&read_finish, tv_start));
if (rc >= read_time) {
if (amt > 0)
applog(LOG_DEBUG, "Icarus Read: Timeout reading for %d ms", rc);
else
applog(LOG_DEBUG, "Icarus Read: No data for %d ms", rc);
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) { cgtime(tv_start);
buf += amt; err = usb_read_ii_timeout_cancellable(icarus, info->intinfo, (char *)buf,
read_amount -= amt; ICARUS_READ_SIZE, &amt, read_time,
first = false; C_GETRESULTS);
} cgtime(tv_finish);
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_ERR, "%s%i: Comms error (rerr=%d amt=%d)", icarus->drv->name,
icarus->device_id, err, amt);
dev_error(icarus, REASON_DEV_COMMS_ERROR);
return ICA_NONCE_ERROR;
}
if (info->timeout < ICARUS_WAIT_TIMEOUT) { if (amt >= ICARUS_READ_SIZE)
delay = ICARUS_WAIT_TIMEOUT - rc; return ICA_NONCE_OK;
if (delay > 0) {
cgsleep_ms(delay);
if (thr && thr->work_restart) { rc = SECTOMS(tdiff(tv_finish, tv_start));
applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc); if (thr && thr->work_restart) {
return ICA_NONCE_RESTART; applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
} return ICA_NONCE_RESTART;
}
}
} }
if (amt > 0)
applog(LOG_DEBUG, "Icarus Read: Timeout reading for %d ms", rc);
else
applog(LOG_DEBUG, "Icarus Read: No data for %d ms", rc);
return ICA_NONCE_TIMEOUT;
} }
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

@ -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

@ -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)
{ {
cgsem_destroy(&ut->cgsem);
libusb_free_transfer(ut->transfer);
cg_wlock(&cgusb_fd_lock); cg_wlock(&cgusb_fd_lock);
cgusb_transfers--; list_del(&ut->list);
cg_wunlock(&cgusb_fd_lock); cg_wunlock(&cgusb_fd_lock);
cgsem_destroy(&ut->cgsem);
libusb_free_transfer(ut->transfer);
} }
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

@ -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

@ -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…
Cancel
Save