Icarus - CMR shouldn't wait the full timeout due to handle sharing
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
diff --git a/driver-icarus.c b/driver-icarus.c
index a42988b..9ad4e43 100644
--- a/driver-icarus.c
+++ b/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
@@ -186,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
@@ -434,7 +437,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
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 +449,7 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
cgtime(&read_start);
err = usb_read_ii_timeout(icarus, info->intinfo,
(char *)buf, read_amount, &amt,
- ICARUS_WAIT_TIMEOUT, C_GETRESULTS);
+ 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)",
@@ -483,6 +486,21 @@ 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) {
+ if (opt_debug) {
+ applog(LOG_DEBUG,
+ "Icarus Read: Work restart at %d ms", rc);
+ }
+ return ICA_NONCE_RESTART;
+ }
+ }
+ }
}
}
@@ -796,6 +814,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 +833,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) {