icarus support CMR with no extensions
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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
diff --git a/driver-icarus.c b/driver-icarus.c
index 647c9d1..42814a1 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -102,7 +102,9 @@ ASSERT1(sizeof(uint32_t) == 4);
#define LANCELOT_HASH_TIME 0.0000000025000
#define ASICMINERUSB_HASH_TIME 0.0000000029761
// TODO: What is it?
-#define CAIRNSMORE1_HASH_TIME 0.0000000026316
+#define CAIRNSMORE1_HASH_TIME 0.0000000027000
+// Per FPGA
+#define CAIRNSMORE2_HASH_TIME 0.0000000066600
#define NANOSEC 1000000000.0
// Icarus Rev3 doesn't send a completion message when it finishes
@@ -208,6 +210,8 @@ struct ICARUS_INFO {
int work_division;
int fpga_count;
uint32_t nonce_mask;
+
+ bool initialised;
};
#define END_CONDITION 0x0000ffff
@@ -262,6 +266,7 @@ static void _transfer(struct cgpu_info *icarus, uint8_t request_type, uint8_t bR
static void icarus_initialise(struct cgpu_info *icarus, int baud)
{
+ struct ICARUS_INFO *info = (struct ICARUS_INFO *)(icarus->device_data);
uint16_t wValue, wIndex;
enum sub_ident ident;
int interface;
@@ -282,6 +287,9 @@ 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);
@@ -403,6 +411,8 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud)
quit(1, "icarus_intialise() called with invalid %s cgid %i ident=%d",
icarus->drv->name, icarus->cgminer_id, ident);
}
+
+ info->initialised = true;
}
static void rev(unsigned char *s, size_t l)
@@ -537,11 +547,12 @@ static void set_timing_mode(int this_option_offset, struct cgpu_info *icarus)
case IDENT_AMU:
info->Hs = ASICMINERUSB_HASH_TIME;
break;
- // TODO: ?
case IDENT_CMR1:
- case IDENT_CMR2:
info->Hs = CAIRNSMORE1_HASH_TIME;
break;
+ case IDENT_CMR2:
+ info->Hs = CAIRNSMORE2_HASH_TIME;
+ break;
default:
quit(1, "Icarus get_options() called with invalid %s ident=%d",
icarus->drv->name, ident);
@@ -701,13 +712,16 @@ static void get_options(int this_option_offset, struct cgpu_info *icarus, int *b
*work_division = 1;
*fpga_count = 1;
break;
- // TODO: ?
case IDENT_CMR1:
- case IDENT_CMR2:
*baud = ICARUS_IO_SPEED;
*work_division = 2;
*fpga_count = 2;
break;
+ case IDENT_CMR2:
+ *baud = ICARUS_IO_SPEED;
+ *work_division = 1;
+ *fpga_count = 1;
+ break;
default:
quit(1, "Icarus get_options() called with invalid %s ident=%d",
icarus->drv->name, ident);
@@ -795,6 +809,11 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
hex2bin(ob_bin, golden_ob, sizeof(ob_bin));
+ info = (struct ICARUS_INFO *)calloc(1, sizeof(struct ICARUS_INFO));
+ if (unlikely(!info))
+ quit(1, "Failed to malloc ICARUS_INFO");
+ icarus->device_data = (void *)info;
+
tries = 2;
ok = false;
while (!ok && tries-- > 0) {
@@ -844,15 +863,6 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
applog(LOG_DEBUG, "%s%d: Init baud=%d work_division=%d fpga_count=%d",
icarus->drv->name, icarus->device_id, baud, work_division, fpga_count);
- info = (struct ICARUS_INFO *)malloc(sizeof(struct ICARUS_INFO));
- if (unlikely(!info))
- quit(1, "Failed to malloc ICARUS_INFO");
-
- icarus->device_data = (void *)info;
-
- // Initialise everything to zero for a new device
- memset(info, 0, sizeof(struct ICARUS_INFO));
-
info->baud = baud;
info->work_division = work_division;
info->fpga_count = fpga_count;
@@ -862,12 +872,47 @@ static bool icarus_detect_one(struct libusb_device *dev, struct usb_find_devices
timersub(&tv_finish, &tv_start, &(info->golden_tv));
set_timing_mode(this_option_offset, icarus);
+
+ if (usb_ident(icarus) == IDENT_CMR2) {
+ int i;
+ for (i = 1; i < icarus->usbdev->found->intinfo_count; i++) {
+ struct cgpu_info *cgtmp;
+ struct ICARUS_INFO *intmp;
+
+ cgtmp = usb_init_intinfo(icarus, i);
+ if (!cgtmp) {
+ applog(LOG_ERR, "%s%d: Init failed initinfo %d",
+ icarus->drv->name, icarus->device_id, i);
+ continue;
+ }
+
+ 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");
+
+ cgtmp->device_data = (void *)intmp;
+
+ // Initialise everything to match
+ memcpy(intmp, info, sizeof(struct ICARUS_INFO));
+ }
+ }
return true;
unshin:
usb_uninit(icarus);
+ free(info);
+ icarus->device_data = NULL;
shin:
@@ -917,6 +962,9 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work,
if (icarus->usbinfo.nodev)
return -1;
+ if (!info->initialised)
+ icarus_initialise(icarus, info->baud);
+
elapsed.tv_sec = elapsed.tv_usec = 0;
memset(ob_bin, 0, sizeof(ob_bin));