static int64_t hashratio_scanhash(struct thr_info *thr) { struct cgpu_info *hashratio = thr->cgpu; struct hashratio_info *info = hashratio->device_data; struct hashratio_pkg send_pkg; struct hashratio_ret ar; memset(send_pkg.data, 0, HRTO_P_DATA_LEN); hashratio_init_pkg(&send_pkg, HRTO_P_POLLING, 1, 1); if (unlikely(hashratio->usbinfo.nodev || hashratio_send_pkgs(hashratio, &send_pkg))) { applog(LOG_ERR, "%s%d: Device disappeared, shutting down thread", hashratio->drv->name, hashratio->device_id); return -1; } hashratio_get_result(thr, &ar); return (int64_t)info->local_work * 64 * 0xffffffff; }
static int polling(struct thr_info *thr) { int i, tmp; struct hashratio_pkg send_pkg; struct hashratio_ret ar; struct cgpu_info *hashratio = thr->cgpu; struct hashratio_info *info = hashratio->device_data; memset(send_pkg.data, 0, HRTO_P_DATA_LEN); hashratio_init_pkg(&send_pkg, HRTO_P_POLLING, 1, 1); while (hashratio_send_pkg(info->fd, &send_pkg, thr) != HRTO_SEND_OK) ; hashratio_get_result(thr, info->fd, &ar); return 0; }
static void hashratio_update_work(struct cgpu_info *hashratio) { struct hashratio_info *info = hashratio->device_data; struct thr_info *thr = hashratio->thr[0]; struct hashratio_pkg send_pkg; uint32_t tmp, range, start; struct work *work; struct pool *pool; applog(LOG_DEBUG, "hashratio: New stratum: restart: %d, update: %d", thr->work_restart, thr->work_update); thr->work_update = false; thr->work_restart = false; work = get_work(thr, thr->id); /* Make sure pool is ready */ discard_work(work); /* Don't leak memory */ pool = current_pool(); if (!pool->has_stratum) quit(1, "hashratio: Miner Manager have to use stratum pool"); if (pool->coinbase_len > HRTO_P_COINBASE_SIZE) quit(1, "hashratio: Miner Manager pool coinbase length have to less then %d", HRTO_P_COINBASE_SIZE); if (pool->merkles > HRTO_P_MERKLES_COUNT) quit(1, "hashratio: Miner Manager merkles have to less then %d", HRTO_P_MERKLES_COUNT); info->pool_no = pool->pool_no; cgtime(&info->last_stratum); cg_rlock(&pool->data_lock); info->pool_no = pool->pool_no; copy_pool_stratum(info, pool); hashratio_stratum_pkgs(hashratio, pool); cg_runlock(&pool->data_lock); /* Configure the parameter from outside */ memset(send_pkg.data, 0, HRTO_P_DATA_LEN); // fan. We're not measuring temperature so set a safe but not max value info->fan_pwm = HRTO_PWM_MAX * 2 / 3; tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); // freq tmp = be32toh(info->default_freq); memcpy(send_pkg.data + 4, &tmp, 4); applog(LOG_DEBUG, "set freq: %d", info->default_freq); /* Configure the nonce2 offset and range */ range = 0xffffffff / (total_devices + 1); start = range * (hashratio->device_id + 1); tmp = be32toh(start); memcpy(send_pkg.data + 8, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 12, &tmp, 4); /* Package the data */ hashratio_init_pkg(&send_pkg, HRTO_P_SET, 1, 1); hashratio_send_pkgs(hashratio, &send_pkg); }
static struct cgpu_info *hashratio_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct hashratio_info *info; int err, amount; int ackdetect; char mm_version[16]; struct cgpu_info *hashratio = usb_alloc_cgpu(&hashratio_drv, 1); struct hashratio_pkg detect_pkg; struct hashratio_ret ret_pkg; if (!usb_init(hashratio, dev, found)) { applog(LOG_ERR, "Hashratio failed usb_init"); hashratio = usb_free_cgpu(hashratio); return NULL; } hashratio_initialise(hashratio); strcpy(mm_version, "NONE"); /* Send out detect pkg */ memset(detect_pkg.data, 0, HRTO_P_DATA_LEN); hashratio_init_pkg(&detect_pkg, HRTO_P_DETECT, 1, 1); hashratio_send_pkg(hashratio, &detect_pkg); err = usb_read(hashratio, (char *)&ret_pkg, HRTO_READ_SIZE, &amount, C_HRO_READ); if (err || amount != HRTO_READ_SIZE) { applog(LOG_ERR, "%s %d: Hashratio failed usb_read with err %d amount %d", hashratio->drv->name, hashratio->device_id, err, amount); usb_uninit(hashratio); usb_free_cgpu(hashratio); return NULL; } ackdetect = ret_pkg.type; applog(LOG_DEBUG, "hashratio Detect ID: %d", ackdetect); if (ackdetect != HRTO_P_ACKDETECT) { applog(LOG_DEBUG, "Not a hashratio device"); usb_uninit(hashratio); usb_free_cgpu(hashratio); return NULL; } memcpy(mm_version, ret_pkg.data, 15); mm_version[15] = '\0'; /* We have a real Hashratio! */ hashratio->threads = HRTO_MINER_THREADS; add_cgpu(hashratio); update_usb_stats(hashratio); applog(LOG_INFO, "%s%d: Found at %s", hashratio->drv->name, hashratio->device_id, hashratio->device_path); hashratio->device_data = cgcalloc(sizeof(struct hashratio_info), 1); info = hashratio->device_data; strcpy(info->mm_version, mm_version); info->fan_pwm = HRTO_DEFAULT_FAN / 100 * HRTO_PWM_MAX; info->temp_max = 0; info->temp_history_index = 0; info->temp_sum = 0; info->temp_old = 0; info->default_freq = hashratio_freq; return hashratio; }
static void hashratio_stratum_pkgs(struct cgpu_info *hashratio, struct pool *pool) { const int merkle_offset = 36; struct hashratio_pkg pkg; int i, a, b, tmp; unsigned char target[32]; int job_id_len; unsigned short crc; /* Send out the first stratum message STATIC */ applog(LOG_DEBUG, "hashratio: Pool stratum message STATIC: %d, %d, %d, %d, %d, %d", pool->coinbase_len, pool->nonce2_offset, pool->n2size, merkle_offset, pool->merkles, pool->pool_no); memset(pkg.data, 0, HRTO_P_DATA_LEN); tmp = be32toh(pool->coinbase_len); memcpy(pkg.data, &tmp, 4); tmp = be32toh(pool->nonce2_offset); memcpy(pkg.data + 4, &tmp, 4); tmp = be32toh(pool->n2size); memcpy(pkg.data + 8, &tmp, 4); tmp = be32toh(merkle_offset); memcpy(pkg.data + 12, &tmp, 4); tmp = be32toh(pool->merkles); memcpy(pkg.data + 16, &tmp, 4); tmp = be32toh((int)pool->sdiff); memcpy(pkg.data + 20, &tmp, 4); tmp = be32toh((int)pool->pool_no); memcpy(pkg.data + 24, &tmp, 4); hashratio_init_pkg(&pkg, HRTO_P_STATIC, 1, 1); if (hashratio_send_pkgs(hashratio, &pkg)) return; set_target(target, pool->sdiff); memcpy(pkg.data, target, 32); if (opt_debug) { char *target_str; target_str = bin2hex(target, 32); applog(LOG_DEBUG, "hashratio: Pool stratum target: %s", target_str); free(target_str); } hashratio_init_pkg(&pkg, HRTO_P_TARGET, 1, 1); if (hashratio_send_pkgs(hashratio, &pkg)) return; applog(LOG_DEBUG, "hashratio: Pool stratum message JOBS_ID: %s", pool->swork.job_id); memset(pkg.data, 0, HRTO_P_DATA_LEN); job_id_len = strlen(pool->swork.job_id); crc = crc16((const unsigned char *)pool->swork.job_id, job_id_len); pkg.data[0] = (crc & 0xff00) >> 8; pkg.data[1] = crc & 0x00ff; hashratio_init_pkg(&pkg, HRTO_P_JOB_ID, 1, 1); if (hashratio_send_pkgs(hashratio, &pkg)) return; a = pool->coinbase_len / HRTO_P_DATA_LEN; b = pool->coinbase_len % HRTO_P_DATA_LEN; applog(LOG_DEBUG, "pool->coinbase_len: %d", pool->coinbase_len); applog(LOG_DEBUG, "hashratio: Pool stratum message COINBASE: %d %d", a, b); for (i = 0; i < a; i++) { memcpy(pkg.data, pool->coinbase + i * 32, 32); hashratio_init_pkg(&pkg, HRTO_P_COINBASE, i + 1, a + (b ? 1 : 0)); if (hashratio_send_pkgs(hashratio, &pkg)) return; if (i % 25 == 0) { cgsleep_ms(2); } } if (b) { memset(pkg.data, 0, HRTO_P_DATA_LEN); memcpy(pkg.data, pool->coinbase + i * 32, b); hashratio_init_pkg(&pkg, HRTO_P_COINBASE, i + 1, i + 1); if (hashratio_send_pkgs(hashratio, &pkg)) return; } b = pool->merkles; applog(LOG_DEBUG, "hashratio: Pool stratum message MERKLES: %d", b); for (i = 0; i < b; i++) { memset(pkg.data, 0, HRTO_P_DATA_LEN); memcpy(pkg.data, pool->swork.merkle_bin[i], 32); hashratio_init_pkg(&pkg, HRTO_P_MERKLES, i + 1, b); if (hashratio_send_pkgs(hashratio, &pkg)) return; } applog(LOG_DEBUG, "hashratio: Pool stratum message HEADER: 4"); for (i = 0; i < 4; i++) { memset(pkg.data, 0, HRTO_P_HEADER); memcpy(pkg.data, pool->header_bin + i * 32, 32); hashratio_init_pkg(&pkg, HRTO_P_HEADER, i + 1, 4); if (hashratio_send_pkgs(hashratio, &pkg)) return; } }
static int64_t hashratio_scanhash(struct thr_info *thr) { struct hashratio_pkg send_pkg; struct pool *pool; struct cgpu_info *hashratio = thr->cgpu; struct hashratio_info *info = hashratio->device_data; struct hashratio_ret ret_pkg; uint32_t tmp, range, start; int i; if (thr->work_restart || thr->work_update || info->first) { info->new_stratum = true; applog(LOG_DEBUG, "hashratio: New stratum: restart: %d, update: %d, first: %d", thr->work_restart, thr->work_update, info->first); thr->work_update = false; thr->work_restart = false; if (unlikely(info->first)) info->first = false; get_work(thr, thr->id); /* Make sure pool is ready */ pool = current_pool(); if (!pool->has_stratum) quit(1, "hashratio: Miner Manager have to use stratum pool"); if (pool->coinbase_len > HRTO_P_COINBASE_SIZE) quit(1, "hashratio: Miner Manager pool coinbase length have to less then %d", HRTO_P_COINBASE_SIZE); if (pool->merkles > HRTO_P_MERKLES_COUNT) quit(1, "hashratio: Miner Manager merkles have to less then %d", HRTO_P_MERKLES_COUNT); info->diff = (int)pool->swork.diff - 1; info->pool_no = pool->pool_no; cg_wlock(&pool->data_lock); hashratio_stratum_pkgs(info->fd, pool, thr); cg_wunlock(&pool->data_lock); /* Configuer the parameter from outside */ memset(send_pkg.data, 0, HRTO_P_DATA_LEN); // fan info->fan_pwm = HRTO_PWM_MAX; tmp = be32toh(info->fan_pwm); memcpy(send_pkg.data, &tmp, 4); // freq tmp = be32toh(info->default_freq); memcpy(send_pkg.data + 4, &tmp, 4); applog(LOG_DEBUG, "set freq: %d", info->default_freq); /* Configure the nonce2 offset and range */ range = 0xffffffff / total_devices; start = range * hashratio->device_id; tmp = be32toh(start); memcpy(send_pkg.data + 8, &tmp, 4); tmp = be32toh(range); memcpy(send_pkg.data + 12, &tmp, 4); /* Package the data */ hashratio_init_pkg(&send_pkg, HRTO_P_SET, 1, 1); while (hashratio_send_pkg(info->fd, &send_pkg, thr) != HRTO_SEND_OK) ; info->new_stratum = false; } polling(thr); return (int64_t)info->local_work * 64 * 0xffffffff; }
static bool hashratio_detect_one(const char *devpath) { struct hashratio_info *info; int ackdetect; int fd; int tmp, i; char mm_version[16]; struct cgpu_info *hashratio; struct hashratio_pkg detect_pkg; struct hashratio_ret ret_pkg; applog(LOG_DEBUG, "hashratio Detect: Attempting to open %s", devpath); fd = hashratio_open(devpath, HRTO_IO_SPEED, true); if (unlikely(fd == -1)) { applog(LOG_ERR, "hashratio Detect: Failed to open %s", devpath); return false; } tcflush(fd, TCIOFLUSH); strcpy(mm_version, "NONE"); /* Send out detect pkg */ memset(detect_pkg.data, 0, HRTO_P_DATA_LEN); hashratio_init_pkg(&detect_pkg, HRTO_P_DETECT, 1, 1); hashratio_send_pkg(fd, &detect_pkg, NULL); ackdetect = hashratio_get_result(NULL, fd, &ret_pkg); applog(LOG_DEBUG, "hashratio Detect ID: %d", ackdetect); if (ackdetect != HRTO_P_ACKDETECT) return false; memcpy(mm_version, ret_pkg.data, 15); mm_version[15] = '\0'; /* We have a real Hashratio! */ hashratio = calloc(1, sizeof(struct cgpu_info)); hashratio->drv = &hashratio_drv; hashratio->device_path = strdup(devpath); hashratio->threads = HRTO_MINER_THREADS; add_cgpu(hashratio); applog(LOG_INFO, "hashratio Detect: Found at %s, mark as %d", devpath, hashratio->device_id); hashratio->device_data = calloc(sizeof(struct hashratio_info), 1); if (unlikely(!(hashratio->device_data))) quit(1, "Failed to malloc hashratio_info"); info = hashratio->device_data; strcpy(info->mm_version, mm_version); info->baud = HRTO_IO_SPEED; info->fan_pwm = HRTO_DEFAULT_FAN / 100 * HRTO_PWM_MAX; info->temp_max = 0; info->temp_history_index = 0; info->temp_sum = 0; info->temp_old = 0; info->default_freq = opt_hashratio_freq; info->fd = -1; /* Set asic to idle mode after detect */ hashratio_close(fd); return true; }
static int hashratio_stratum_pkgs(int fd, struct pool *pool, struct thr_info *thr) { const int merkle_offset = 36; struct hashratio_pkg pkg; int i, a, b, tmp; unsigned char target[32]; int job_id_len; /* Send out the first stratum message STATIC */ applog(LOG_DEBUG, "hashratio: Pool stratum message STATIC: %d, %d, %d, %d, %d, %d", pool->coinbase_len, pool->nonce2_offset, pool->n2size, merkle_offset, pool->merkles, pool->pool_no); memset(pkg.data, 0, HRTO_P_DATA_LEN); tmp = be32toh(pool->coinbase_len); memcpy(pkg.data, &tmp, 4); tmp = be32toh(pool->nonce2_offset); memcpy(pkg.data + 4, &tmp, 4); tmp = be32toh(pool->n2size); memcpy(pkg.data + 8, &tmp, 4); tmp = be32toh(merkle_offset); memcpy(pkg.data + 12, &tmp, 4); tmp = be32toh(pool->merkles); memcpy(pkg.data + 16, &tmp, 4); tmp = be32toh((int)pool->swork.diff); memcpy(pkg.data + 20, &tmp, 4); tmp = be32toh((int)pool->pool_no); memcpy(pkg.data + 24, &tmp, 4); hashratio_init_pkg(&pkg, HRTO_P_STATIC, 1, 1); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; set_target(target, pool->swork.diff); memcpy(pkg.data, target, 32); if (opt_debug) { char *target_str; target_str = bin2hex(target, 32); applog(LOG_DEBUG, "hashratio: Pool stratum target: %s", target_str); free(target_str); } hashratio_init_pkg(&pkg, HRTO_P_TARGET, 1, 1); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; applog(LOG_DEBUG, "hashratio: Pool stratum message JOBS_ID: %s", pool->swork.job_id); memset(pkg.data, 0, HRTO_P_DATA_LEN); job_id_len = strlen(pool->swork.job_id); job_id_len = job_id_len >= 4 ? 4 : job_id_len; for (i = 0; i < job_id_len; i++) { pkg.data[i] = *(pool->swork.job_id + strlen(pool->swork.job_id) - 4 + i); } hashratio_init_pkg(&pkg, HRTO_P_JOB_ID, 1, 1); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; a = pool->coinbase_len / HRTO_P_DATA_LEN; b = pool->coinbase_len % HRTO_P_DATA_LEN; applog(LOG_DEBUG, "pool->coinbase_len: %d", pool->coinbase_len); applog(LOG_DEBUG, "hashratio: Pool stratum message COINBASE: %d %d", a, b); for (i = 0; i < a; i++) { memcpy(pkg.data, pool->coinbase + i * 32, 32); hashratio_init_pkg(&pkg, HRTO_P_COINBASE, i + 1, a + (b ? 1 : 0)); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; if (i % 25 == 0) { cgsleep_ms(2); } } if (b) { memset(pkg.data, 0, HRTO_P_DATA_LEN); memcpy(pkg.data, pool->coinbase + i * 32, b); hashratio_init_pkg(&pkg, HRTO_P_COINBASE, i + 1, i + 1); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; } b = pool->merkles; applog(LOG_DEBUG, "hashratio: Pool stratum message MERKLES: %d", b); for (i = 0; i < b; i++) { memset(pkg.data, 0, HRTO_P_DATA_LEN); memcpy(pkg.data, pool->swork.merkle_bin[i], 32); hashratio_init_pkg(&pkg, HRTO_P_MERKLES, i + 1, b); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; } applog(LOG_DEBUG, "hashratio: Pool stratum message HEADER: 4"); for (i = 0; i < 4; i++) { memset(pkg.data, 0, HRTO_P_HEADER); memcpy(pkg.data, pool->header_bin + i * 32, 32); hashratio_init_pkg(&pkg, HRTO_P_HEADER, i + 1, 4); while (hashratio_send_pkg(fd, &pkg, thr) != HRTO_SEND_OK) ; } return 0; }