Use cancellable usb transfers in the icarus driver to avoid having to loop and poll when waiting for a response and to speed up work restart response time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
diff --git a/driver-icarus.c b/driver-icarus.c
index 871e178..5b0af8d 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -471,70 +471,42 @@ static void rev(unsigned char *s, size_t l)
#define ICA_NONCE_RESTART 1
#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 timeval read_start, read_finish;
- int err, amt;
- int rc = 0, delay;
- int read_amount = ICARUS_READ_SIZE;
- bool first = true;
+ int err, amt, rc;
- cgtime(tv_start);
- while (true) {
- 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 (icarus->usbinfo.nodev)
+ return ICA_NONCE_ERROR;
- if (amt > 0) {
- buf += amt;
- read_amount -= amt;
- first = false;
- }
+ cgtime(tv_start);
+ err = usb_read_ii_timeout_cancellable(icarus, info->intinfo, (char *)buf,
+ ICARUS_READ_SIZE, &amt, read_time,
+ 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) {
- delay = ICARUS_WAIT_TIMEOUT - rc;
- if (delay > 0) {
- cgsleep_ms(delay);
+ if (amt >= ICARUS_READ_SIZE)
+ return ICA_NONCE_OK;
- if (thr && thr->work_restart) {
- applog(LOG_DEBUG, "Icarus Read: Work restart at %d ms", rc);
- return ICA_NONCE_RESTART;
- }
- }
- }
+ rc = SECTOMS(tdiff(tv_finish, tv_start));
+ if (thr->work_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)