static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_candidate_nonce *n = (struct hf_candidate_nonce *)(h + 1); int i, num_nonces = h->data_length / U32SIZE(sizeof(struct hf_candidate_nonce)); applog(LOG_DEBUG, "%s %d: OP_NONCE: %2d/%2d:, num_nonces %d hdata 0x%04x", hashfast->drv->name, hashfast->device_id, h->chip_address, h->core_address, num_nonces, h->hdata); for (i = 0; i < num_nonces; i++, n++) { struct work *work = NULL; applog(LOG_DEBUG, "%s %d: OP_NONCE: %2d: %2d: ntime %2d sequence %4d nonce 0x%08x", hashfast->drv->name, hashfast->device_id, h->chip_address, i, n->ntime & HF_NTIME_MASK, n->sequence, n->nonce); if (n->sequence < info->usb_init_base.sequence_modulus) { // Find the job from the sequence number mutex_lock(&info->lock); work = info->works[n->sequence]; mutex_unlock(&info->lock); } else { applog(LOG_INFO, "%s %d: OP_NONCE: Sequence out of range %4d max %4d", hashfast->drv->name, hashfast->device_id, n->sequence, info->usb_init_base.sequence_modulus); } if (unlikely(!work)) { info->no_matching_work++; applog(LOG_INFO, "%s %d: No matching work!", hashfast->drv->name, hashfast->device_id); } else { applog(LOG_DEBUG, "%s %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d", hashfast->drv->name, hashfast->device_id, n->sequence, n->nonce, n->ntime & HF_NTIME_MASK); if (submit_noffset_nonce(thr, work, n->nonce, n->ntime & HF_NTIME_MASK)) { mutex_lock(&info->lock); info->hash_count += 0xffffffffull * work->device_diff; mutex_unlock(&info->lock); } #if 0 /* Not used */ if (unlikely(n->ntime & HF_NONCE_SEARCH)) { /* This tells us there is another share in the * next 128 nonces */ applog(LOG_DEBUG, "%s %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND", hashfast->drv->name, hashfast->device_id); } #endif } } }
static void hfa_parse_nonce(struct thr_info *thr, struct cgpu_info *hashfast, struct hashfast_info *info, struct hf_header *h) { struct hf_candidate_nonce *n = (struct hf_candidate_nonce *)(h + 1); int i, num_nonces = h->data_length / U32SIZE(sizeof(struct hf_candidate_nonce)); applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d:, num_nonces %d hdata 0x%04x", hashfast->device_id, h->chip_address, num_nonces, h->hdata); for (i = 0; i < num_nonces; i++, n++) { struct work *work = NULL; applog(LOG_DEBUG, "HFA %d: OP_NONCE: %2d: %2d: ntime %2d sequence %4d nonce 0x%08x", hashfast->device_id, h->chip_address, i, n->ntime & HF_NTIME_MASK, n->sequence, n->nonce); if (n->sequence < info->usb_init_base.sequence_modulus) { // Find the job from the sequence number mutex_lock(&info->lock); work = info->works[n->sequence]; mutex_unlock(&info->lock); } else { applog(LOG_INFO, "HFA %d: OP_NONCE: Sequence out of range %4d max %4d", hashfast->device_id, n->sequence, info->usb_init_base.sequence_modulus); } if (unlikely(!work)) { info->no_matching_work++; applog(LOG_INFO, "HFA %d: No matching work!", hashfast->device_id); } else { applog(LOG_DEBUG, "HFA %d: OP_NONCE: sequence %d: submitting nonce 0x%08x ntime %d", hashfast->device_id, n->sequence, n->nonce, n->ntime & HF_NTIME_MASK); if ((n->nonce & 0xffff0000) == 0x42420000) // XXX REMOVE THIS break; // XXX PHONEY EMULATOR NONCE submit_noffset_nonce(thr, work, n->nonce, n->ntime & HF_NTIME_MASK); // XXX Return value from submit_nonce is error if set if (unlikely(n->ntime & HF_NONCE_SEARCH)) { /* This tells us there is another share in the * next 128 nonces */ applog(LOG_DEBUG, "HFA %d: OP_NONCE: SEARCH PROXIMITY EVENT FOUND", hashfast->device_id); search_for_extra_nonce(thr, work, n); } } } }
// Return completed work to submit_nonce() and work_completed() // struct timeval last_force_queue = {0}; static int64_t spond_scanhash_sp30(struct thr_info *thr) { struct cgpu_info *cgpu = thr->cgpu; struct spond_adapter *a = cgpu->device_data; int64_t ghashes = 0; cgtimer_t cgt; time_t now_t; cgsleep_prepare_r(&cgt); now_t = time(NULL); /* Poll stats only once per second */ if (now_t != a->last_stats) { a->last_stats = now_t; spond_poll_stats(cgpu, a); } if (a->parse_resp) { int array_size, i; mutex_lock(&a->lock); //ghashes = (a->mp_last_rsp->gh_div_50_rate); //ghashes = ghashes * 50000 * REQUEST_PERIOD; array_size = a->mp_last_rsp->rsp_count; for (i = 0; i < array_size; i++) { // walk the jobs int job_id; minergate_do_job_rsp_sp30* work = a->mp_last_rsp->rsp + i; job_id = work->work_id_in_sw; if ((a->my_jobs[job_id].cgminer_work)) { if (a->my_jobs[job_id].merkle_root == work->mrkle_root) { assert(a->my_jobs[job_id].state == SPONDWORK_STATE_IN_BUSY); if (work->winner_nonce) { struct work *cg_work = a->my_jobs[job_id].cgminer_work; bool ok; ok = submit_noffset_nonce(cg_work->thr, cg_work, work->winner_nonce, work->ntime_offset); if (ok) ghashes += 0xffffffffull * cg_work->device_diff; /*printf("WIn on %d (+%d), none=%x = %d\n", * work->work_id_in_sw, work->ntime_offset, htole32(work->winner_nonce), ok);*/ a->wins++; } //printf("%d ntime_clones = %d\n",job_id,a->my_jobs[job_id].ntime_clones); //printf("Done with %d\n", job_id); if (work->job_complete) { //printf("Complete %d\n", job_id); work_completed(a->cgpu, a->my_jobs[job_id].cgminer_work); a->good++; a->my_jobs[job_id].cgminer_work = NULL; a->my_jobs[job_id].state = SPONDWORK_STATE_EMPTY; a->works_in_minergate_and_pending_tx--; a->works_in_driver--; } } else { a->bad++; applog(LOG_DEBUG, "SP30: Dropping minergate old job id=%d mrkl=%x my-mrkl=%x", job_id, a->my_jobs[job_id].merkle_root, work->mrkle_root); } } else { a->empty++; applog(LOG_DEBUG, "SP30: No cgminer job (id:%d res:%d)!",job_id, work->res); } } mutex_unlock(&a->lock); a->parse_resp = 0; } cgsleep_ms_r(&cgt, 40); return ghashes; }