コード例 #1
0
ファイル: driver-hashfast.c プロジェクト: uraymeiviar/cgminer
static bool hfa_get_header(struct cgpu_info *hashfast, struct hf_header *h, uint8_t *computed_crc)
{
    int amount, ret, orig_len, len, ofs = 0;
    cgtimer_t ts_start;
    char buf[512];
    char *header;

    orig_len = len = sizeof(*h);

    /* Read for up to 200ms till we find the first occurrence of HF_PREAMBLE
     * though it should be the first byte unless we get woefully out of
     * sync. */
    cgtimer_time(&ts_start);
    do {
        cgtimer_t ts_now, ts_diff;

        cgtimer_time(&ts_now);
        cgtimer_sub(&ts_now, &ts_start, &ts_diff);
        if (cgtimer_to_ms(&ts_diff) > 200)
            return false;

        ret = usb_read(hashfast, buf + ofs, len, &amount, C_HF_GETHEADER);
        if (unlikely(ret && ret != LIBUSB_ERROR_TIMEOUT))
            return false;
        ofs += amount;
        header = memchr(buf, HF_PREAMBLE, ofs);
        if (header)
            len -= ofs - (header - buf);
    } while (len);

    memcpy(h, header, orig_len);
    *computed_crc = hfa_crc8((uint8_t *)h);

    return true;
}
コード例 #2
0
ファイル: driver-gridseed.c プロジェクト: 91thUb/usb-miner
static bool gridseed_prepare(struct thr_info *thr)
{
	struct cgpu_info *gridseed = thr->cgpu;
	GRIDSEED_INFO *info = gridseed->device_data;

	info->thr = thr;
	mutex_init(&info->lock);
	mutex_init(&info->qlock);

	info->queued = 0;
	info->dev_queue_len = GRIDSEED_MCU_QUEUE_LEN;
	info->soft_queue_len = 0;
	info->query_qlen = false;
	info->needworks = 0;
	memset(&info->workqueue, 0, sizeof(struct work *)*GRIDSEED_SOFT_QUEUE_LEN);
	cgtimer_time(&info->query_ts);
	info->workdone = 0;

	if (info->sockltc > 0)
		close(info->sockltc);
	info->sockltc = -1;

	if (pthread_create(&info->th_read, NULL, gridseed_get_results, (void*)gridseed))
		quit(1, "Failed to create GridSeed read thread");

	if (pthread_create(&info->th_send, NULL, gridseed_send_command, (void*)gridseed))
		quit(1, "Failed to create GridSeed send thread");

	gridseed_create_proxy(gridseed, info);
	gridseed_request_ltc_task(gridseed, info);

	applog(LOG_NOTICE, "GridSeed device opened on %s", gridseed->device_path);
	return true;
}
コード例 #3
0
ファイル: driver-gridseed.c プロジェクト: 91thUb/usb-miner
static void gridseed_get_queue_length(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
		unsigned char *data)
{
	uint32_t qlen;

	memcpy(&qlen, data+8, 4);
	qlen = htole32(qlen);

	mutex_lock(&info->qlock);
	info->query_qlen = false;
	info->dev_queue_len = GRIDSEED_MCU_QUEUE_LEN - qlen;
	info->needworks = qlen;
	cgtimer_time(&info->query_ts);
	mutex_unlock(&info->qlock);
	return;
}
コード例 #4
0
ファイル: driver-gridseed.c プロジェクト: 91thUb/usb-miner
static bool gridseed_send_query_cmd(struct cgpu_info *gridseed, GRIDSEED_INFO *info)
{
	unsigned char *cmd = "\x55\xaa\xc0\x00\xa0\xa0\xa0\xa0\x00\x00\x00\x00\x01\x00\x00\x00";
	cgtimer_t ts_now, ts_res;
	bool ret = false;

	cgtimer_time(&ts_now);
	mutex_lock(&info->qlock);
	if (!info->query_qlen) {
		cgtimer_sub(&ts_now, &info->query_ts, &ts_res);
#ifndef WIN32
		if (ts_res.tv_sec > 0) {
#else
		if (ts_res.QuadPart > 10000000) {
#endif
			if (gc3355_write_data(gridseed, cmd, 16) == 0) {
				info->query_qlen = true;
				ret = true;
			}
		}
	}
	mutex_unlock(&info->qlock);
	return ret;
}

static bool gridseed_send_task(struct cgpu_info *gridseed, GRIDSEED_INFO *info,
			struct work *work)
{
	unsigned char cmd[52];

	memcpy(cmd, "\x55\xaa\x0f\x01", 4);
	memcpy(cmd+4, work->midstate, 32);
	memcpy(cmd+36, work->data+64, 12);
	memcpy(cmd+48, &(work->id), 4);
	return (gc3355_write_data(gridseed, cmd, sizeof(cmd)) == 0);
}
コード例 #5
0
ファイル: driver-gridseed.c プロジェクト: 91thUb/usb-miner
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);
}