Exemplo n.º 1
0
static int64_t gridseed_scanhash(struct thr_info *thr, struct work *work, int64_t __maybe_unused max_nonce)
{
	struct cgpu_info *gridseed = thr->cgpu;
	GRIDSEED_INFO *info = gridseed->device_data;
	unsigned char buf[GRIDSEED_READ_SIZE];
	int ret = 0;
	struct timeval old_scanhash_time = info->scanhash_time;
	int elapsed_ms;

	while (!thr->work_restart && (ret = gc3355_get_data(gridseed, buf, GRIDSEED_READ_SIZE)) == 0) {
		if (buf[0] == 0x55 || buf[1] == 0x20) {
			uint32_t nonce = le32toh(*(uint32_t *)(buf+4));
			uint32_t chip = nonce / ((uint32_t)0xffffffff / info->chips);
			info->nonce_count[chip]++;
			if (!submit_nonce(thr, work, nonce))
				info->error_count[chip]++;
		} else {
			applog(LOG_ERR, "Unrecognized response from %i", gridseed->device_id);
			return -1;
		}
	}
	if (ret != 0 && ret != LIBUSB_ERROR_TIMEOUT) {
		applog(LOG_ERR, "No response from %i", gridseed->device_id);
		return -1;
	}

	cgtime(&info->scanhash_time);
	elapsed_ms = ms_tdiff(&info->scanhash_time, &old_scanhash_time);
	return GRIDSEED_HASH_SPEED * (double)elapsed_ms * (double)(info->freq * info->chips);
}
Exemplo n.º 2
0
static bool gc3355_write_register(struct cgpu_info *gridseed, uint32_t reg_addr,
				  uint32_t reg_value) {
	GRIDSEED_INFO *info = (GRIDSEED_INFO*)(gridseed->device_data);
	char cmd[16] = "\x55\xaa\xc0\x02";
	uint32_t reg_len = 4;
	unsigned char buf[4];

	if (info->fw_version != 0x01140113) {
		applog(LOG_ERR, "Can't write registers; incompatible firmware %08X on %i",
			info->fw_version, gridseed->device_id);
		return false;
	}

	*(uint32_t *)(cmd + 4) = htole32(reg_addr);
	*(uint32_t *)(cmd + 8) = htole32(reg_value);
	*(uint32_t *)(cmd + 12) = htole32(reg_len);
	if (gc3355_write_data(gridseed, cmd, sizeof(cmd)) != 0) {
		applog(LOG_DEBUG, "Failed to write data to %i", gridseed->device_id);
		return false;
	}
	cgsleep_ms(GRIDSEED_COMMAND_DELAY);

	if (gc3355_get_data(gridseed, buf, 4)) {
		applog(LOG_DEBUG, "No response from %i", gridseed->device_id);
		return false;
	}
	return true;
}
Exemplo n.º 3
0
static bool gridseed_detect_one(libusb_device *dev, struct usb_find_devices *found)
{
	struct cgpu_info *gridseed;
	GRIDSEED_INFO *info;
	int err, wrote, def_freq_inx;
	unsigned char rbuf[GRIDSEED_READ_SIZE];
#if 0
	const char detect_cmd[] =
		"55aa0f01"
		"4a548fe471fa3a9a1371144556c3f64d"
		"2500b4826008fe4bbf7698c94eba7946"
		"ce22a72f4f6726141a0b3287eeeeeeee";
	unsigned char detect_data[52];
#else
	const char detect_cmd[] = "55aac000909090900000000001000000";
	unsigned char detect_data[16];
#endif

	gridseed = usb_alloc_cgpu(&gridseed_drv, GRIDSEED_MINER_THREADS);
	if (!usb_init(gridseed, dev, found))
		goto shin;

	libusb_reset_device(gridseed->usbdev->handle);

	info = (GRIDSEED_INFO*)calloc(sizeof(GRIDSEED_INFO), 1);
	if (unlikely(!info))
		quit(1, "Failed to calloc gridseed_info data");
	gridseed->device_data = (void *)info;

	info->baud = GRIDSEED_DEFAULT_BAUD;
	info->freq = GRIDSEED_DEFAULT_FREQUENCY;
	def_freq_inx = gc3355_find_freq_index(GRIDSEED_DEFAULT_FREQUENCY);
	memcpy(info->freq_cmd, bin_frequency[def_freq_inx], 8);
	info->chips = GRIDSEED_DEFAULT_CHIPS;
	info->voltage = 0;
	info->per_chip_stats = 0;
	info->serial = strdup(gridseed->usbdev->serial_string);
	memset(info->nonce_count, 0, sizeof(info->nonce_count));
	memset(info->error_count, 0, sizeof(info->error_count));

	get_options(info, opt_gridseed_options);
	get_freq(info, opt_gridseed_freq);
	get_chips(info, opt_gridseed_chips);

	update_usb_stats(gridseed);

	gridseed->usbdev->usb_type = USB_TYPE_STD;
	gridseed_initialise(gridseed, info);

	/* get MCU firmware version */
	hex2bin(detect_data, detect_cmd, sizeof(detect_data));
	if (gc3355_write_data(gridseed, detect_data, sizeof(detect_data))) {
		applog(LOG_DEBUG, "Failed to write work data to %i, err %d",
			gridseed->device_id, err);
		goto unshin;
	}

	/* waiting for return */
	if (gc3355_get_data(gridseed, rbuf, GRIDSEED_READ_SIZE)) {
		applog(LOG_DEBUG, "No response from %i", gridseed->device_id);
		goto unshin;
	}

	if (memcmp(rbuf, "\x55\xaa\xc0\x00\x90\x90\x90\x90", GRIDSEED_READ_SIZE-4) != 0) {
		applog(LOG_DEBUG, "Bad response from %i",
			gridseed->device_id);
		goto unshin;
	}

	info->fw_version = le32toh(*(uint32_t *)(rbuf+8));
	applog(LOG_NOTICE, "Device found, firmware version %08X, driver version %s",
		info->fw_version, gridseed_version);

	gc3355_init(gridseed, info);

	gridseed->algorithm = default_algorithm;

	if (!add_cgpu(gridseed))
		goto unshin;

	return true;

unshin:
	usb_uninit(gridseed);
	free(gridseed->device_data);
	gridseed->device_data = NULL;

shin:
	gridseed = usb_free_cgpu(gridseed);
	return false;
}
Exemplo n.º 4
0
static struct cgpu_info *gridseed_detect_one(libusb_device *dev, struct usb_find_devices *found)
{
	struct cgpu_info *gridseed;
	GRIDSEED_INFO *info;
	int this_option_offset;
	int baud, freq, chips, modules, usefifo, btcore;
	int err, wrote;
	bool configured;
	unsigned char rbuf[GRIDSEED_READ_SIZE];
	unsigned char *p;
#if 0
	const char detect_cmd[] =
		"55aa0f01"
		"4a548fe471fa3a9a1371144556c3f64d"
		"2500b4826008fe4bbf7698c94eba7946"
		"ce22a72f4f6726141a0b3287eeeeeeee";
	unsigned char detect_data[52];
#else
	const char detect_cmd[] = "55aac000909090900000000001000000";
	unsigned char detect_data[16];
#endif

	gridseed = usb_alloc_cgpu(&gridseed_drv, GRIDSEED_MINER_THREADS);
	if (!usb_init(gridseed, dev, found))
		goto shin;

	libusb_reset_device(gridseed->usbdev->handle);

	baud = GRIDSEED_DEFAULT_BAUD;
	chips = GRIDSEED_DEFAULT_CHIPS;
	modules = GRIDSEED_DEFAULT_MODULES;
	freq = gc3355_find_freq_index(GRIDSEED_DEFAULT_FREQUENCY);
	usefifo = GRIDSEED_DEFAULT_USEFIFO;
	btcore = GRIDSEED_DEFAULT_BTCORE;

	this_option_offset = 0;
	configured = get_options(this_option_offset, gridseed, opt_gridseed_options,
		&baud, &freq, &chips, &modules, &usefifo, &btcore);

	info = (GRIDSEED_INFO*)calloc(sizeof(GRIDSEED_INFO), 1);
	if (unlikely(!info))
		quit(1, "Failed to calloc gridseed_info data");
	gridseed->device_data = (void *)info;

	update_usb_stats(gridseed);

	//if (configured) {
		info->baud = baud;
		info->freq = freq;
		info->chips = chips;
		info->modules = modules;
		info->usefifo = usefifo;
		info->btcore = btcore;
	//}

	gridseed->usbdev->usb_type = USB_TYPE_STD;
	gridseed_initialise(gridseed, info);

	/* send testing work to chips */
	hex2bin(detect_data, detect_cmd, sizeof(detect_data));
	if (gc3355_write_data(gridseed, detect_data, sizeof(detect_data))) {
		applog(LOG_DEBUG, "Failed to write work data to %i, err %d",
			gridseed->device_id, err);
		goto unshin;
	}

	/* waiting for return */
	if (gc3355_get_data(gridseed, rbuf, GRIDSEED_READ_SIZE)) {
		applog(LOG_DEBUG, "No response from %i",
			gridseed->device_id);
		goto unshin;
	}

	if (memcmp(rbuf, "\x55\xaa\xc0\x00\x90\x90\x90\x90", GRIDSEED_READ_SIZE-4) != 0) {
		applog(LOG_DEBUG, "Bad response from %i",
			gridseed->device_id);
		goto unshin;
	}

	p = bin2hex(rbuf+GRIDSEED_READ_SIZE-4, 4);
	applog(LOG_NOTICE, "Device found, firmware version 0x%s, driver version %s", p, gridseed_version);
	free(p);

	if (!add_cgpu(gridseed))
		goto unshin;

	return gridseed;

unshin:
	usb_uninit(gridseed);
	free(gridseed->device_data);
	gridseed->device_data = NULL;

shin:
	gridseed = usb_free_cgpu(gridseed);
	return NULL;
}
Exemplo n.º 5
0
static bool gridseed_check_new_task(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
{
	cgtimer_t ts_now, ts_res;
	bool ret = false;

	cgtimer_time(&ts_now);
	mutex_lock(&info->qlock);
	cgtimer_sub(&ts_now, &info->query_ts, &ts_res);
#ifndef WIN32
	if (ts_res.tv_sec > 0 || ts_res.tv_nsec > 350000000) {
#else
	if (ts_res.QuadPart > 3500000) {
#endif
		info->query_qlen = false;
		info->dev_queue_len = 1;
		info->needworks = 1;
		cgtimer_time(&info->query_ts);
	}
	mutex_unlock(&info->qlock);
}

/*
 * Thread to read response from Miner device
 */
static void *gridseed_get_results(void *userdata)
{
	struct cgpu_info *gridseed = (struct cgpu_info *)userdata;
	GRIDSEED_INFO *info = gridseed->device_data;
	struct thr_info *thr = info->thr;
	char threadname[24];
	unsigned char readbuf[GRIDSEED_READBUF_SIZE];
	int offset = 0, ret;

	snprintf(threadname, sizeof(threadname), "GridSeed_Recv/%d", gridseed->device_id);
	RenameThread(threadname);
	applog(LOG_NOTICE, "GridSeed: recv thread running, %s", threadname);

	while(likely(!gridseed->shutdown)) {
		unsigned char buf[GRIDSEED_READ_SIZE];

		if (offset >= GRIDSEED_READ_SIZE)
			gridseed_parse_results(gridseed, info, thr, readbuf, &offset);

		if (unlikely(offset + GRIDSEED_READ_SIZE >= GRIDSEED_READBUF_SIZE)) {
			applog(LOG_ERR, "Read buffer overflow, resetting %d", gridseed->device_id);
			offset = 0;
		}

		ret = gc3355_get_data(gridseed, buf, sizeof(buf));
		if (ret == LIBUSB_ERROR_NO_DEVICE)
			gridseed->shutdown = true;
		if (unlikely(ret != 0))
			continue;

		if (opt_debug) {
			applog(LOG_DEBUG, "GridSeed: get %d bytes", GRIDSEED_READ_SIZE);
			hexdump((uint8_t *)buf, GRIDSEED_READ_SIZE);
		}

		memcpy(readbuf + offset, buf, GRIDSEED_READ_SIZE);
		offset += GRIDSEED_READ_SIZE;
	}
	return NULL;
}

/*
 * Thread to send task and queue length query command to device
 */
static void *gridseed_send_command(void *userdata)
{
	struct cgpu_info *gridseed = (struct cgpu_info *)userdata;
	GRIDSEED_INFO *info = gridseed->device_data;
	char threadname[24];
	int i;

	snprintf(threadname, sizeof(threadname), "GridSeed_Send/%d", gridseed->device_id);
	RenameThread(threadname);
	applog(LOG_NOTICE, "GridSeed: send thread running, %s", threadname);

	while(likely(!gridseed->shutdown)) {
		cgsleep_ms(10);
		if (info->usefifo == 0) {
			/* mark the first work in queue as complete after several ms */
			if (gridseed_check_new_task(gridseed, info))
				continue;
		} else {
			/* send query command to device */
			if (gridseed_send_query_cmd(gridseed, info))
				continue;
		}
		/* send task to device */
		mutex_lock(&info->qlock);
		for(i=0; i<info->soft_queue_len; i++) {
			if (info->workqueue[i] && info->workqueue[i]->devflag == false) {
				if (gridseed_send_task(gridseed, info, info->workqueue[i])) {
					info->workqueue[i]->devflag = true;
					break;
				}
			}
		}
		mutex_unlock(&info->qlock);
		/* recv LTC task and send to device */
		gridseed_recv_ltc(gridseed, info);
	}
	return NULL;
}

/*========== functions for struct device_drv ===========*/

static void gridseed_detect(bool __maybe_unused hotplug)
{
	usb_detect(&gridseed_drv, gridseed_detect_one);
}