Merge branch 'master' of https://github.com/Roanoak/cgminer into hfa
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
diff --git a/driver-hashfast.c b/driver-hashfast.c
index 7549a83..61fc303 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -128,14 +128,17 @@ static bool hfa_send_frame(struct cgpu_info *hashfast, uint8_t opcode, uint16_t
return true;
}
-static bool hfa_send_header(struct cgpu_info *hashfast, struct hf_header *h, int cmd)
+/* Send an already assembled packet, consisting of an 8 byte header which may
+ * or may not be followed by a packet body. */
+
+static bool hfa_send_packet(struct cgpu_info *hashfast, struct hf_header *h, int cmd)
{
int amount, ret, len;
- len = sizeof(*h);
+ len = sizeof(*h) + h->data_length*4;
ret = usb_write(hashfast, (char *)h, len, &amount, hfa_cmds[cmd].usb_cmd);
if (ret < 0 || amount != len) {
- applog(LOG_WARNING, "HFA%d: send_header: %s USB Send error, ret %d amount %d vs. length %d",
+ applog(LOG_WARNING, "HFA%d: send_packet: %s USB Send error, ret %d amount %d vs. length %d",
hashfast->device_id, hfa_cmds[cmd].cmd_name, ret, amount, len);
return false;
}
@@ -187,33 +190,58 @@ static bool hfa_get_data(struct cgpu_info *hashfast, char *buf, int len4)
return true;
}
+static const char *hf_usb_init_errors[] = {
+ "Success",
+ "Reset timeout",
+ "Address cycle timeout",
+ "Clockgate operation timeout",
+ "Configuration operation timeout",
+ "Excessive core failures",
+ "All cores failed diagnostics",
+ "Too many groups configured - increase ntime roll amount"
+ };
+
+
static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
{
struct hf_usb_init_header usb_init, *hu = &usb_init;
struct hf_usb_init_base *db;
+ struct hf_usb_init_options *ho;
char buf[1024];
struct hf_header *h = (struct hf_header *)buf;
uint8_t hcrc;
bool ret;
int i;
+ // XXX Following items need to be defaults with command-line overrides
info->hash_clock_rate = 550; // Hash clock rate in Mhz
+ info->group_ntime_roll = 1;
+ info->core_ntime_roll = 1;
+
// Assemble the USB_INIT request
memset(hu, 0, sizeof(*hu));
hu->preamble = HF_PREAMBLE;
hu->operation_code = OP_USB_INIT;
hu->protocol = PROTOCOL_GLOBAL_WORK_QUEUE; // Protocol to use
hu->hash_clock = info->hash_clock_rate; // Hash clock rate in Mhz
+ if (info->group_ntime_roll > 1 && info->core_ntime_roll) {
+ ho = (struct hf_usb_init_options *)(hu+1);
+ memset(ho, 0, sizeof(*ho));
+ ho->group_ntime_roll = info->group_ntime_roll;
+ ho->core_ntime_roll = info->core_ntime_roll;
+ hu->data_length = sizeof(*ho)/4;
+ }
hu->crc8 = hfa_crc8((uint8_t *)hu);
applog(LOG_INFO, "HFA%d: Sending OP_USB_INIT with GWQ protocol specified",
hashfast->device_id);
-
- if (!hfa_send_header(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT)))
+
+ if (!hfa_send_packet(hashfast, (struct hf_header *)hu, HF_USB_CMD(OP_USB_INIT)))
return false;
// Check for the correct response.
// We extend the normal timeout - a complete device initialization, including
// bringing power supplies up from standby, etc., can take over a second.
+tryagain:
for (i = 0; i < 30; i++) {
ret = hfa_get_header(hashfast, h, &hcrc);
if (ret)
@@ -228,9 +256,12 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
return false;
}
if (h->operation_code != OP_USB_INIT) {
- applog(LOG_WARNING, "HFA %d: OP_USB_INIT: Tossing packet, valid but unexpected type", hashfast->device_id);
+ // This can happen if valid packet(s) were in transit *before* the OP_USB_INIT arrived
+ // at the device, so we just toss the packets and keep looking for the response.
+ applog(LOG_WARNING, "HFA %d: OP_USB_INIT: Tossing packet, valid but unexpected type %d",
+ hashfast->device_id, h->operation_code);
hfa_get_data(hashfast, buf, h->data_length);
- return false;
+ goto tryagain;
}
applog(LOG_DEBUG, "HFA %d: Good reply to OP_USB_INIT", hashfast->device_id);
@@ -286,6 +317,15 @@ static bool hfa_reset(struct cgpu_info *hashfast, struct hashfast_info *info)
return false;
}
+ // See if the initialization suceeded
+ if (db->operation_status) {
+ applog(LOG_WARNING, "HFA %d: OP_USB_INIT failed! Operation status %d (%s)",
+ hashfast->device_id, db->operation_status,
+ (db->operation_status < sizeof(hf_usb_init_errors)/sizeof(hf_usb_init_errors[0])) ?
+ hf_usb_init_errors[db->operation_status] : "Unknown error code");
+ return false;
+ }
+
return true;
}
diff --git a/driver-hashfast.h b/driver-hashfast.h
index 6c8efb2..5c8acb0 100644
--- a/driver-hashfast.h
+++ b/driver-hashfast.h
@@ -79,6 +79,8 @@ struct hashfast_info {
struct hf_config_data config_data; // Configuration data used from USB_INIT
int core_bitmap_size; // in bytes
uint32_t *core_bitmap; // Core OK bitmap test results, run with PLL Bypassed
+ int group_ntime_roll; // Total ntime roll amount per group
+ int core_ntime_roll; // Total core ntime roll amount
pthread_mutex_t lock;
struct work **works;