Browse Source

Implement reading of a whole hashfast packet from the read thread and parsing it, implementing parsing of gwq status.

nfactor-troky
Con Kolivas 11 years ago
parent
commit
f340c52c88
  1. 83
      driver-hashfast.c
  2. 12
      driver-hashfast.h

83
driver-hashfast.c

@ -267,6 +267,9 @@ static bool hashfast_reset(struct cgpu_info *hashfast, struct hashfast_info *inf
db->hash_clockrate); db->hash_clockrate);
applog(LOG_INFO, "HFA %d: inflight_target: %d", hashfast->device_id, applog(LOG_INFO, "HFA %d: inflight_target: %d", hashfast->device_id,
db->inflight_target); db->inflight_target);
applog(LOG_INFO, "HFA %d: sequence_modulus: %d", hashfast->device_id,
db->sequence_modulus);
info->num_sequence = db->sequence_modulus;
// Now a copy of the config data used // Now a copy of the config data used
if (!hashfast_get_data(hashfast, (char *)&info->config_data, U32SIZE(info->config_data))) { if (!hashfast_get_data(hashfast, (char *)&info->config_data, U32SIZE(info->config_data))) {
@ -314,7 +317,7 @@ static bool hashfast_detect_common(struct cgpu_info *hashfast)
if (unlikely(!(info->die_statistics))) if (unlikely(!(info->die_statistics)))
quit(1, "Failed to calloc die_statistics"); quit(1, "Failed to calloc die_statistics");
info->works = calloc(sizeof(struct work *), HF_NUM_SEQUENCE); info->works = calloc(sizeof(struct work *), info->num_sequence);
if (!info->works) if (!info->works)
quit(1, "Failed to calloc info works in hashfast_detect_common"); quit(1, "Failed to calloc info works in hashfast_detect_common");
@ -358,6 +361,62 @@ static void hashfast_detect(bool hotplug)
usb_detect(&hashfast_drv, hashfast_detect_one_usb); usb_detect(&hashfast_drv, hashfast_detect_one_usb);
} }
static bool hashfast_get_packet(struct cgpu_info *hashfast, struct hf_header *h)
{
uint8_t hcrc;
bool ret;
ret = hashfast_get_header(hashfast, h, &hcrc);
if (unlikely(!ret))
goto out;
if (unlikely(h->crc8 != hcrc)) {
applog(LOG_WARNING, "HFA %d: Bad CRC %d vs %d, attempting to process anyway",
hashfast->device_id, h->crc8, hcrc);
}
if (h->data_length > 0)
ret = hashfast_get_data(hashfast, (char *)(h + 1), h->data_length);
if (unlikely(!ret)) {
applog(LOG_WARNING, "HFA %d: Failed to get data associated with header",
hashfast->device_id);
}
out:
return ret;
}
static void hfa_parse_gwq_status(struct cgpu_info *hashfast, struct hashfast_info *info,
struct hf_header *h)
{
struct hf_gwq_data *g = (struct hf_gwq_data *)(h + 1);
struct work *work;
applog(LOG_DEBUG, "HFA %d: OP_GWQ_STATUS, device_head %4d tail %4d my tail %4d shed %3d inflight %4d",
hashfast->device_id, g->sequence_head, g->sequence_tail, info->hash_sequence_tail,
g->shed_count, SEQUENCE_DISTANCE(info->hash_sequence_head,g->sequence_tail));
mutex_lock(&info->lock);
info->hash_count += g->hash_count;
info->device_sequence_head = g->sequence_head;
info->device_sequence_tail = g->sequence_tail;
info->shed_count = g->shed_count;
/* Free any work that is no longer required */
while (info->device_sequence_tail != info->hash_sequence_tail) {
if (++info->hash_sequence_tail >= info->num_sequence)
info->hash_sequence_tail = 0;
if (unlikely(!(work = info->works[info->hash_sequence_tail]))) {
applog(LOG_ERR, "HFA %d: Bad work sequence tail",
hashfast->device_id);
hashfast->shutdown = true;
break;
}
applog(LOG_DEBUG, "HFA %d: Completing work on hash_sequence_tail %d",
hashfast->device_id, info->hash_sequence_tail);
free_work(work);
info->works[info->hash_sequence_tail] = NULL;
}
mutex_unlock(&info->lock);
}
static void *hfa_read(void *arg) static void *hfa_read(void *arg)
{ {
struct thr_info *thr = (struct thr_info *)arg; struct thr_info *thr = (struct thr_info *)arg;
@ -369,6 +428,24 @@ static void *hfa_read(void *arg)
RenameThread(threadname); RenameThread(threadname);
while (likely(!hashfast->shutdown)) { while (likely(!hashfast->shutdown)) {
char buf[512];
struct hf_header *h = (struct hf_header *)buf;
bool ret = hashfast_get_packet(hashfast, h);
if (unlikely(!ret))
continue;
switch (h->operation_code) {
case OP_GWQ_STATUS:
hfa_parse_gwq_status(hashfast, info, h);
break;
case OP_DIE_STATUS:
case OP_NONCE:
case OP_STATISTICS:
case OP_USB_STATS1:
default:
break;
}
} }
return NULL; return NULL;
@ -393,7 +470,7 @@ static bool hashfast_prepare(struct thr_info *thr)
/* Figure out how many jobs to send. */ /* Figure out how many jobs to send. */
static int __hashfast_jobs(struct hashfast_info *info) static int __hashfast_jobs(struct hashfast_info *info)
{ {
return info->usb_init_base.inflight_target - GWQ_SEQUENCE_DISTANCE(info->hash_sequence, info->device_sequence_tail); return info->usb_init_base.inflight_target - HF_SEQUENCE_DISTANCE(info->hash_sequence, info->device_sequence_tail);
} }
static int hashfast_jobs(struct hashfast_info *info) static int hashfast_jobs(struct hashfast_info *info)
@ -459,7 +536,7 @@ restart:
intdiff = (uint64_t)work->device_diff; intdiff = (uint64_t)work->device_diff;
for (i = 31; intdiff; i++, intdiff >>= 1); for (i = 31; intdiff; i++, intdiff >>= 1);
op_hash_data.search_difficulty = i; op_hash_data.search_difficulty = i;
if ((sequence = info->hash_sequence + 1) >= HF_NUM_SEQUENCE) if ((sequence = info->hash_sequence + 1) >= info->num_sequence)
sequence = 0; sequence = 0;
ret = hashfast_send_frame(hashfast, OP_HASH, sequence, (uint8_t *)&op_hash_data, sizeof(op_hash_data)); ret = hashfast_send_frame(hashfast, OP_HASH, sequence, (uint8_t *)&op_hash_data, sizeof(op_hash_data));
if (unlikely(!ret)) { if (unlikely(!ret)) {

12
driver-hashfast.h

@ -17,8 +17,7 @@
#include "hf_protocol.h" #include "hf_protocol.h"
#define HASHFAST_MINER_THREADS 1 #define HASHFAST_MINER_THREADS 1
#define HF_NUM_SEQUENCE 256 #define HF_SEQUENCE_DISTANCE(tx,rx) ((tx)>=(rx)?((tx)-(rx)):(info->num_sequence+(tx)-(rx)))
#define GWQ_SEQUENCE_DISTANCE(tx,rx) ((tx)>=(rx)?((tx)-(rx)):(HF_NUM_SEQUENCE+(tx)-(rx)))
// Matching fields for hf_statistics, but large #'s for local accumulation, per-die // Matching fields for hf_statistics, but large #'s for local accumulation, per-die
struct hf_long_statistics { struct hf_long_statistics {
@ -35,6 +34,7 @@ struct hashfast_info {
int asic_count; // # of chips in the chain int asic_count; // # of chips in the chain
int core_count; // # of cores per chip int core_count; // # of cores per chip
int device_type; // What sort of device this is int device_type; // What sort of device this is
int num_sequence; // A power of 2. What the sequence number range is.
int ref_frequency; // Reference clock rate int ref_frequency; // Reference clock rate
uint16_t hash_sequence; // The next hash sequence # to be sent uint16_t hash_sequence; // The next hash sequence # to be sent
struct hf_g1_die_data *die_status; // Array of per-die voltage, current, temperature sensor data struct hf_g1_die_data *die_status; // Array of per-die voltage, current, temperature sensor data
@ -47,10 +47,12 @@ struct hashfast_info {
pthread_mutex_t lock; pthread_mutex_t lock;
struct work **works; struct work **works;
uint16_t device_sequence_head; // The most recent sequence number the device dispatched uint16_t hash_sequence_head; // HOST: The next hash sequence # to be sent
uint16_t device_sequence_tail; // The most recently completed job in the device uint16_t hash_sequence_tail; // HOST: Follows device_sequence_tail around to free work
uint16_t hash_sequence_tail; // Follows device_sequence_tail around to free work uint16_t device_sequence_head; // DEVICE: The most recent sequence number the device dispatched
uint16_t device_sequence_tail; // DEVICE: The most recently completed job in the device
int64_t hash_count; int64_t hash_count;
uint16_t shed_count; // Dynamic copy of #cores device has shed for thermal control
pthread_t read_thr; pthread_t read_thr;
}; };

Loading…
Cancel
Save