Use op_name if possible first with hfa devices to detect old instances and be able to choose the starting clockspeed before sending an init sequence, reverting to setting op name and serial number as fallbacks.
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 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
diff --git a/driver-hashfast.c b/driver-hashfast.c
index 81fca7f..7cfc2e0 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -345,7 +345,7 @@ static void hfa_choose_opname(struct cgpu_info *hashfast, struct hashfast_info *
uint64_t usecs;
if (info->serial_number)
- sprintf(info->op_name, "%x", info->serial_number);
+ sprintf(info->op_name, "%08x", info->serial_number);
else {
struct timeval tv_now;
@@ -367,7 +367,8 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
uint8_t hcrc;
bool ret;
- /* Hash clock rate in Mhz */
+ /* Hash clock rate in Mhz. Set to opt_hfa_hash_clock if it has not
+ * been inherited across a restart. */
if (!info->hash_clock_rate)
info->hash_clock_rate = opt_hfa_hash_clock;
info->group_ntime_roll = opt_hfa_ntime_roll;
@@ -466,7 +467,7 @@ tryagain:
(db->firmware_rev >> 8) & 0xff, db->firmware_rev & 0xff);
applog(LOG_INFO, "%s %d: hardware_rev: %d.%d", hashfast->drv->name, hashfast->device_id,
(db->hardware_rev >> 8) & 0xff, db->hardware_rev & 0xff);
- applog(LOG_INFO, "%s %d: serial number: 0x%08x", hashfast->drv->name, hashfast->device_id,
+ applog(LOG_INFO, "%s %d: serial number: %08x", hashfast->drv->name, hashfast->device_id,
db->serial_number);
applog(LOG_INFO, "%s %d: hash clockrate: %d Mhz", hashfast->drv->name, hashfast->device_id,
db->hash_clockrate);
@@ -511,37 +512,6 @@ tryagain:
hfa_clear_readbuf(hashfast);
- /* Try sending and receiving an OP_NAME */
- if (!hfa_send_frame(hashfast, HF_USB_CMD(OP_NAME), 0, (uint8_t *)NULL, 0)) {
- applog(LOG_WARNING, "%s %d: Failed to send OP_NAME!", hashfast->drv->name,
- hashfast->device_id);
- return false;
- }
- ret = hfa_get_header(hashfast, h, &hcrc);
- if (!ret) {
- applog(LOG_WARNING, "%s %d: Failed to receive OP_NAME response", hashfast->drv->name,
- hashfast->device_id);
- return false;
- }
- /* Only try to parse the name if the firmware supports OP_NAME */
- if (h->operation_code == OP_NAME) {
- if (!hfa_get_data(hashfast, info->op_name, 32)) {
- applog(LOG_WARNING, "%s %d: OP_NAME failed! Failure to get op_name data",
- hashfast->drv->name, hashfast->device_id);
- return false;
- }
- for (i = 0; i < 32; i++) {
- if (i > 0 && info->op_name[i] == '\0')
- break;
- /* Make sure the op_name is valid ascii only */
- if (info->op_name[i] < 32 || info->op_name[i] > 126) {
- hfa_choose_opname(hashfast, info);
- break;
- }
- }
- applog(LOG_INFO, "%s %d: Opname set to %s", hashfast->drv->name,
- hashfast->device_id, info->op_name);
- }
return true;
}
@@ -602,14 +572,10 @@ static struct cgpu_info *hfa_old_device(struct cgpu_info *hashfast, struct hashf
if (!cinfo)
continue;
if (info->op_name[0] != '\0' && !strncmp(info->op_name, cinfo->op_name, 32)) {
- applog(LOG_DEBUG, "%s %d: Found old device based on OP_NAME %s",
- hashfast->drv->name, hashfast->device_id, info->op_name);
found = cgpu;
break;
}
if (info->serial_number && info->serial_number == cinfo->serial_number) {
- applog(LOG_DEBUG, "%s %d: Found old device based on serial number %x",
- hashfast->drv->name, hashfast->device_id, info->serial_number);
found = cgpu;
break;
}
@@ -634,19 +600,79 @@ static void hfa_set_clock(struct cgpu_info *hashfast, struct hashfast_info *info
static bool hfa_detect_common(struct cgpu_info *hashfast)
{
+ bool has_opname = false, opname_valid = true, ret = false;
struct hashfast_info *info;
- bool ret = false;
+ char buf[1024];
+ struct hf_header *h = (struct hf_header *)buf;
+ uint8_t hcrc;
int i;
info = calloc(sizeof(struct hashfast_info), 1);
if (!info)
quit(1, "Failed to calloc hashfast_info in hfa_detect_common");
hashfast->device_data = info;
+
+ /* Try sending and receiving an OP_NAME */
+ if (!hfa_send_frame(hashfast, HF_USB_CMD(OP_NAME), 0, (uint8_t *)NULL, 0)) {
+ applog(LOG_WARNING, "%s %d: Failed to send OP_NAME!", hashfast->drv->name,
+ hashfast->device_id);
+ return false;
+ }
+ ret = hfa_get_header(hashfast, h, &hcrc);
+ if (!ret) {
+ /* We should receive a response even if it OP_NAME isn't
+ * supported. */
+ applog(LOG_WARNING, "%s: Failed to receive OP_NAME response", hashfast->drv->name);
+ return false;
+ }
+
+ /* Only try to parse the name if the firmware supports OP_NAME */
+ if (h->operation_code == OP_NAME) {
+ if (!hfa_get_data(hashfast, info->op_name, 32 / 4)) {
+ applog(LOG_WARNING, "%s %d: OP_NAME failed! Failure to get op_name data",
+ hashfast->drv->name, hashfast->device_id);
+ return false;
+ }
+ has_opname = true;
+ applog(LOG_DEBUG, "%s: Returned an OP_NAME", hashfast->drv->name);
+ for (i = 0; i < 32; i++) {
+ if (i > 0 && info->op_name[i] == '\0')
+ break;
+ /* Make sure the op_name is valid ascii only */
+ if (info->op_name[i] < 32 || info->op_name[i] > 126) {
+ opname_valid = false;
+ break;
+ }
+ }
+ }
+
+ info->cgpu = hashfast;
+ /* Look for a matching zombie instance and inherit values from it if it
+ * exists. */
+ if (has_opname && opname_valid) {
+ info->old_cgpu = hfa_old_device(hashfast, info);
+ if (info->old_cgpu) {
+ struct hashfast_info *cinfo = info->old_cgpu->device_data;
+
+ applog(LOG_NOTICE, "%s: Found old instance by op name %s at device %d",
+ hashfast->drv->name, info->op_name, info->old_cgpu->device_id);
+ info->resets = cinfo->resets;
+ info->hash_clock_rate = cinfo->hash_clock_rate;
+ } else {
+ applog(LOG_NOTICE, "%s: Found device with name %s", hashfast->drv->name,
+ info->op_name);
+ }
+ }
+
/* hashfast_reset should fill in details for info */
ret = hfa_reset(hashfast, info);
if (!ret)
goto out;
+ /* We will have extracted the serial number by now */
+ if (has_opname && !opname_valid)
+ hfa_choose_opname(hashfast, info);
+
if (hashfast->usbinfo.nodev) {
ret = false;
goto out;
@@ -672,15 +698,17 @@ static bool hfa_detect_common(struct cgpu_info *hashfast)
if (!info->works)
quit(1, "Failed to calloc info works in hfa_detect_common");
- info->cgpu = hashfast;
- /* Look for a matching zombie instance and inherit values from it if it
- * exists. */
- info->old_cgpu = hfa_old_device(hashfast, info);
- if (info->old_cgpu) {
+ /* If we haven't found a matching old instance, we might not have
+ * a valid op_name yet or lack support so try to match based on
+ * serial number. */
+ if (!info->old_cgpu)
+ info->old_cgpu = hfa_old_device(hashfast, info);
+
+ if (!has_opname && info->old_cgpu) {
struct hashfast_info *cinfo = info->old_cgpu->device_data;
- applog(LOG_INFO, "Found matching zombie device for %s %d at device %d",
- hashfast->drv->name, hashfast->device_id, info->old_cgpu->device_id);
+ applog(LOG_NOTICE, "%s: Found old instance by serial number %08x at device %d",
+ hashfast->drv->name, info->serial_number, info->old_cgpu->device_id);
info->resets = cinfo->resets;
/* Set the device with the last hash_clock_rate if it's
* different. */