static void copy_pool_stratum(struct pool *pool) { int i; int merkles = pool->merkles; size_t coinbase_len = pool->coinbase_len; if (!job_idcmp(pool->swork.job_id, pool_stratum.swork.job_id)) return; cg_wlock(&(pool_stratum.data_lock)); free(pool_stratum.swork.job_id); free(pool_stratum.nonce1); free(pool_stratum.coinbase); align_len(&coinbase_len); pool_stratum.coinbase = calloc(coinbase_len, 1); if (unlikely(!pool_stratum.coinbase)) quit(1, "Failed to calloc pool_stratum coinbase in avalon2"); memcpy(pool_stratum.coinbase, pool->coinbase, coinbase_len); for (i = 0; i < pool_stratum.merkles; i++) free(pool_stratum.swork.merkle_bin[i]); if (merkles) { pool_stratum.swork.merkle_bin = realloc(pool_stratum.swork.merkle_bin, sizeof(char *) * merkles + 1); for (i = 0; i < merkles; i++) { pool_stratum.swork.merkle_bin[i] = malloc(32); if (unlikely(!pool_stratum.swork.merkle_bin[i])) quit(1, "Failed to malloc pool_stratum swork merkle_bin"); memcpy(pool_stratum.swork.merkle_bin[i], pool->swork.merkle_bin[i], 32); } } pool_stratum.sdiff = pool->sdiff; pool_stratum.coinbase_len = pool->coinbase_len; pool_stratum.nonce2_offset = pool->nonce2_offset; pool_stratum.n2size = pool->n2size; pool_stratum.merkles = pool->merkles; pool_stratum.swork.job_id = strdup(pool->swork.job_id); pool_stratum.nonce1 = strdup(pool->nonce1); memcpy(pool_stratum.ntime, pool->ntime, sizeof(pool_stratum.ntime)); memcpy(pool_stratum.header_bin, pool->header_bin, sizeof(pool_stratum.header_bin)); cg_wunlock(&(pool_stratum.data_lock)); }
static void copy_pool_stratum(struct hashratio_info *info, struct pool *pool) { int i; int merkles = pool->merkles; size_t coinbase_len = pool->coinbase_len; struct pool *pool_stratum = &info->pool; if (!job_idcmp((uint8_t *)pool->swork.job_id, pool_stratum->swork.job_id)) return; cg_wlock(&(pool_stratum->data_lock)); free(pool_stratum->swork.job_id); free(pool_stratum->nonce1); free(pool_stratum->coinbase); pool_stratum->coinbase = cgcalloc(coinbase_len, 1); memcpy(pool_stratum->coinbase, pool->coinbase, coinbase_len); for (i = 0; i < pool_stratum->merkles; i++) free(pool_stratum->swork.merkle_bin[i]); if (merkles) { pool_stratum->swork.merkle_bin = cgrealloc(pool_stratum->swork.merkle_bin, sizeof(char *) * merkles + 1); for (i = 0; i < merkles; i++) { pool_stratum->swork.merkle_bin[i] = cgmalloc(32); memcpy(pool_stratum->swork.merkle_bin[i], pool->swork.merkle_bin[i], 32); } } pool_stratum->sdiff = pool->sdiff; pool_stratum->coinbase_len = pool->coinbase_len; pool_stratum->nonce2_offset = pool->nonce2_offset; pool_stratum->n2size = pool->n2size; pool_stratum->merkles = pool->merkles; pool_stratum->swork.job_id = strdup(pool->swork.job_id); pool_stratum->nonce1 = strdup(pool->nonce1); memcpy(pool_stratum->ntime, pool->ntime, sizeof(pool_stratum->ntime)); memcpy(pool_stratum->header_bin, pool->header_bin, sizeof(pool_stratum->header_bin)); cg_wunlock(&(pool_stratum->data_lock)); }
static int decode_pkg(struct thr_info *thr, struct avalon2_ret *ar, uint8_t *pkg) { struct cgpu_info *avalon2; struct avalon2_info *info; struct pool *pool; unsigned int expected_crc; unsigned int actual_crc; uint32_t nonce, nonce2, miner, modular_id; int pool_no; uint8_t job_id[5]; int tmp; int type = AVA2_GETS_ERROR; if (thr) { avalon2 = thr->cgpu; info = avalon2->device_data; } memcpy((uint8_t *)ar, pkg, AVA2_READ_SIZE); if (ar->head[0] == AVA2_H1 && ar->head[1] == AVA2_H2) { expected_crc = crc16(ar->data, AVA2_P_DATA_LEN); actual_crc = (ar->crc[0] & 0xff) | ((ar->crc[1] & 0xff) << 8); type = ar->type; applog(LOG_DEBUG, "Avalon2: %d: expected crc(%04x), actural_crc(%04x)", type, expected_crc, actual_crc); if (expected_crc != actual_crc) goto out; memcpy(&modular_id, ar->data + 28, 4); modular_id = be32toh(modular_id); if (modular_id == 3) modular_id = 0; switch(type) { case AVA2_P_NONCE: memcpy(&miner, ar->data + 0, 4); memcpy(&pool_no, ar->data + 4, 4); memcpy(&nonce2, ar->data + 8, 4); /* Calc time ar->data + 12 */ memcpy(&nonce, ar->data + 16, 4); memset(job_id, 0, 5); memcpy(job_id, ar->data + 20, 4); miner = be32toh(miner); pool_no = be32toh(pool_no); if (miner >= AVA2_DEFAULT_MINERS || modular_id >= AVA2_DEFAULT_MINERS || pool_no >= total_pools || pool_no < 0) { applog(LOG_DEBUG, "Avalon2: Wrong miner/pool/id no %d,%d,%d", miner, pool_no, modular_id); break; } else info->matching_work[modular_id * AVA2_DEFAULT_MINERS + miner]++; nonce2 = bswap_32(nonce2); nonce = be32toh(nonce); nonce -= 0x180; applog(LOG_DEBUG, "Avalon2: Found! [%s] %d:(%08x) (%08x)", job_id, pool_no, nonce2, nonce); /* FIXME: * We need remember the pre_pool. then submit the stale work */ pool = pools[pool_no]; if (job_idcmp(job_id, pool->swork.job_id)) break; if (thr && !info->new_stratum) submit_nonce2_nonce(thr, pool_no, nonce2, nonce); break; case AVA2_P_STATUS: memcpy(&tmp, ar->data, 4); tmp = be32toh(tmp); info->temp[0 + modular_id * 2] = tmp >> 16; info->temp[1 + modular_id * 2] = tmp & 0xffff; memcpy(&tmp, ar->data + 4, 4); tmp = be32toh(tmp); info->fan[0 + modular_id * 2] = tmp >> 16; info->fan[1 + modular_id * 2] = tmp & 0xffff; memcpy(&(info->get_frequency[modular_id]), ar->data + 8, 4); memcpy(&(info->get_voltage[modular_id]), ar->data + 12, 4); memcpy(&(info->local_work[modular_id]), ar->data + 16, 4); memcpy(&(info->hw_work[modular_id]), ar->data + 20, 4); info->get_frequency[modular_id] = be32toh(info->get_frequency[modular_id]); info->get_voltage[modular_id] = be32toh(info->get_voltage[modular_id]); info->local_work[modular_id] = be32toh(info->local_work[modular_id]); info->hw_work[modular_id] = be32toh(info->hw_work[modular_id]); info->local_works[modular_id] += info->local_work[modular_id]; info->hw_works[modular_id] += info->hw_work[modular_id]; info->get_voltage[modular_id] = decode_voltage(info->get_voltage[modular_id]); avalon2->temp = get_temp_max(info); break; case AVA2_P_ACKDETECT: break; case AVA2_P_ACK: break; case AVA2_P_NAK: break; default: type = AVA2_GETS_ERROR; break; } }
static int decode_pkg(struct thr_info *thr, struct hashratio_ret *ar, uint8_t *pkg) { struct cgpu_info *hashratio = thr->cgpu; struct hashratio_info *info = hashratio->device_data; struct pool *pool, *real_pool, *pool_stratum = &info->pool; unsigned int expected_crc; unsigned int actual_crc; uint32_t nonce, nonce2, miner; int pool_no; uint8_t job_id[4]; int tmp; int type = HRTO_GETS_ERROR; memcpy((uint8_t *)ar, pkg, HRTO_READ_SIZE); // applog(LOG_DEBUG, "pkg.type, hex: %02x, dec: %d", ar->type, ar->type); if (ar->head[0] == HRTO_H1 && ar->head[1] == HRTO_H2) { expected_crc = crc16(ar->data, HRTO_P_DATA_LEN); actual_crc = (ar->crc[0] & 0xff) | ((ar->crc[1] & 0xff) << 8); type = ar->type; applog(LOG_DEBUG, "hashratio: %d: expected crc(%04x), actual_crc(%04x)", type, expected_crc, actual_crc); if (expected_crc != actual_crc) goto out; switch(type) { case HRTO_P_NONCE: applog(LOG_DEBUG, "Hashratio: HRTO_P_NONCE"); memcpy(&miner, ar->data + 0, 4); memcpy(&pool_no, ar->data + 4, 4); memcpy(&nonce2, ar->data + 8, 4); /* Calc time ar->data + 12 */ memcpy(&nonce, ar->data + 12, 4); memcpy(job_id, ar->data + 16, 4); miner = be32toh(miner); pool_no = be32toh(pool_no); if (miner >= HRTO_DEFAULT_MINERS || pool_no >= total_pools || pool_no < 0) { applog(LOG_DEBUG, "hashratio: Wrong miner/pool/id no %d,%d", miner, pool_no); break; } else info->matching_work[miner]++; nonce2 = be32toh(nonce2); nonce = be32toh(nonce); applog(LOG_DEBUG, "hashratio: Found! [%s] %d:(%08x) (%08x)", job_id, pool_no, nonce2, nonce); real_pool = pool = pools[pool_no]; if (job_idcmp(job_id, pool->swork.job_id)) { if (!job_idcmp(job_id, pool_stratum->swork.job_id)) { applog(LOG_DEBUG, "Hashratio: Match to previous stratum! (%s)", pool_stratum->swork.job_id); pool = pool_stratum; } else { applog(LOG_DEBUG, "Hashratio Cannot match to any stratum! (%s)", pool->swork.job_id); break; } } submit_nonce2_nonce(thr, pool, real_pool, nonce2, nonce, 0); break; case HRTO_P_STATUS: applog(LOG_DEBUG, "Hashratio: HRTO_P_STATUS"); memcpy(&tmp, ar->data, 4); tmp = be32toh(tmp); info->temp = (tmp & 0x00f0) >> 8; if (info->temp_max < info->temp) { info->temp_max = info->temp; } // info->temp[1] = tmp & 0xffff; memcpy(&tmp, ar->data + 4, 4); tmp = be32toh(tmp); info->fan[0] = tmp >> 16; info->fan[1] = tmp & 0xffff; // local_work memcpy(&tmp, ar->data + 8, 4); tmp = be32toh(tmp); info->local_work = tmp; info->local_works += tmp; // hw_work memcpy(&tmp, ar->data + 12, 4); tmp = be32toh(tmp); info->hw_works += tmp; hashratio->temp = info->temp; break; case HRTO_P_ACKDETECT: applog(LOG_DEBUG, "Hashratio: HRTO_P_ACKDETECT"); break; case HRTO_P_ACK: applog(LOG_DEBUG, "Hashratio: HRTO_P_ACK"); break; case HRTO_P_NAK: applog(LOG_DEBUG, "Hashratio: HRTO_P_NAK"); break; default: applog(LOG_DEBUG, "Hashratio: HRTO_GETS_ERROR"); type = HRTO_GETS_ERROR; break; } }