static void bitforce_flash_led(struct cgpu_info *bitforce)
{
	int err, amount;

	/* Do not try to flash the led if we're polling for a result to
	 * minimise the chance of interleaved results */
	if (bitforce->polling)
		return;

	/* It is not critical flashing the led so don't get stuck if we
	 * can't grab the mutex now */
	if (mutex_trylock(&bitforce->device_mutex))
		return;

	if ((err = usb_write(bitforce, BITFORCE_FLASH, BITFORCE_FLASH_LEN, &amount, C_REQUESTFLASH)) < 0 || amount != BITFORCE_FLASH_LEN) {
		applog(LOG_ERR, "%s%i: flash request failed (%d:%d)",
			bitforce->drv->name, bitforce->device_id, amount, err);
	} else {
		/* However, this stops anything else getting a reply
		 * So best to delay any other access to the BFL */
		nmsleep(4000);
	}

	/* Once we've tried - don't do it until told to again */
	bitforce->flash_led = false;

	mutex_unlock(&bitforce->device_mutex);

	return; // nothing is returned by the BFL
}
Beispiel #2
0
void bitforce_init(struct cgpu_info *bitforce)
{
	char *devpath = bitforce->device_path;
	int fdDev = bitforce->device_fd, retries = 0;
	char pdevbuf[0x100];
	char *s;

	applog(LOG_WARNING, "BFL%i: Re-initialising", bitforce->device_id);

	bitforce_clear_buffer(bitforce);

	mutex_lock(&bitforce->device_mutex);
	if (fdDev) {
		BFclose(fdDev);
		sleep(5);
	}
	bitforce->device_fd = 0;

	fdDev = BFopen(devpath);
	if (unlikely(fdDev == -1)) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "BFL%i: Failed to open %s", bitforce->device_id, devpath);
		return;
	}

	do {
		BFwrite(fdDev, "ZGX", 3);
		pdevbuf[0] = '\0';
		BFgets(pdevbuf, sizeof(pdevbuf), fdDev);

		if (unlikely(!pdevbuf[0])) {
			mutex_unlock(&bitforce->device_mutex);
			applog(LOG_ERR, "BFL%i: Error reading/timeout (ZGX)", bitforce->device_id);
			return;
		}

		if (retries++)
			nmsleep(10);
	} while (!strstr(pdevbuf, "BUSY") && (retries * 10 < BITFORCE_TIMEOUT_MS));

	if (unlikely(!strstr(pdevbuf, "SHA256"))) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "BFL%i: Didn't recognise BitForce on %s returned: %s", bitforce->device_id, devpath, pdevbuf);
		return;
	}
	
	if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) {
		s[0] = '\0';
		bitforce->name = strdup(pdevbuf + 7);
	}

	bitforce->device_fd = fdDev;
	bitforce->sleep_ms = BITFORCE_SLEEP_MS;

	mutex_unlock(&bitforce->device_mutex);
}
Beispiel #3
0
static bool bitforce_thread_init(struct thr_info *thr)
{
	struct cgpu_info *bitforce = thr->cgpu;
	unsigned int wait;

	/* Pause each new thread at least 100ms between initialising
	 * so the devices aren't making calls all at the same time. */
	wait = thr->id * MAX_START_DELAY_MS;
	applog(LOG_DEBUG, "BFL%i: Delaying start by %dms", bitforce->device_id, wait / 1000);
	nmsleep(wait);

	return true;
}
Beispiel #4
0
static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
{
	struct cgpu_info *bitforce = thr->cgpu;
	int fdDev = bitforce->device_fd;
	unsigned int delay_time_ms;
	struct timeval elapsed;
	struct timeval now;
	char pdevbuf[0x100];
	char *pnoncebuf;
	uint32_t nonce;

	if (!fdDev)
		return -1;

	while (1) {
		if (unlikely(thr->work_restart))
			return 0;

		mutex_lock(&bitforce->device_mutex);
		BFwrite(fdDev, "ZFX", 3);
		BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
		mutex_unlock(&bitforce->device_mutex);

		gettimeofday(&now, NULL);
		timersub(&now, &bitforce->work_start_tv, &elapsed);

		if (elapsed.tv_sec >= BITFORCE_LONG_TIMEOUT_S) {
			applog(LOG_ERR, "BFL%i: took %dms - longer than %dms", bitforce->device_id,
				tv_to_ms(elapsed), BITFORCE_LONG_TIMEOUT_MS);
			return 0;
		}

		if (pdevbuf[0] && strncasecmp(pdevbuf, "B", 1)) /* BFL does not respond during throttling */
			break;

		/* if BFL is throttling, no point checking so quickly */
		delay_time_ms = (pdevbuf[0] ? BITFORCE_CHECK_INTERVAL_MS : 2 * WORK_CHECK_INTERVAL_MS);
		nmsleep(delay_time_ms);
		bitforce->wait_ms += delay_time_ms;
	}

	if (elapsed.tv_sec > BITFORCE_TIMEOUT_S) {
		applog(LOG_ERR, "BFL%i: took %dms - longer than %dms", bitforce->device_id,
			tv_to_ms(elapsed), BITFORCE_TIMEOUT_MS);
		bitforce->device_last_not_well = time(NULL);
		bitforce->device_not_well_reason = REASON_DEV_OVER_HEAT;
		bitforce->dev_over_heat_count++;

		if (!pdevbuf[0])	/* Only return if we got nothing after timeout - there still may be results */
			return 0;
	} else if (!strncasecmp(pdevbuf, "N", 1)) {/* Hashing complete (NONCE-FOUND or NO-NONCE) */
		/* Simple timing adjustment. Allow a few polls to cope with
		 * OS timer delays being variably reliable. wait_ms will
		 * always equal sleep_ms when we've waited greater than or
		 * equal to the result return time.*/
		delay_time_ms = bitforce->sleep_ms;

		if (bitforce->wait_ms > bitforce->sleep_ms + (WORK_CHECK_INTERVAL_MS * 2))
			bitforce->sleep_ms += (bitforce->wait_ms - bitforce->sleep_ms) / 2;
		else if (bitforce->wait_ms == bitforce->sleep_ms) {
			if (bitforce->sleep_ms > WORK_CHECK_INTERVAL_MS)
				bitforce->sleep_ms -= WORK_CHECK_INTERVAL_MS;
			else if (bitforce->sleep_ms > BITFORCE_CHECK_INTERVAL_MS)
				bitforce->sleep_ms -= BITFORCE_CHECK_INTERVAL_MS;
		}

		if (delay_time_ms != bitforce->sleep_ms)
			  applog(LOG_DEBUG, "BFL%i: Wait time changed to: %d, waited %u", bitforce->device_id, bitforce->sleep_ms, bitforce->wait_ms);

		/* Work out the average time taken. Float for calculation, uint for display */
		bitforce->avg_wait_f += (tv_to_ms(elapsed) - bitforce->avg_wait_f) / TIME_AVG_CONSTANT;
		bitforce->avg_wait_d = (unsigned int) (bitforce->avg_wait_f + 0.5);
	}

	applog(LOG_DEBUG, "BFL%i: waited %dms until %s", bitforce->device_id, bitforce->wait_ms, pdevbuf);
	if (!strncasecmp(&pdevbuf[2], "-", 1))
		return bitforce->nonces;   /* No valid nonce found */
	else if (!strncasecmp(pdevbuf, "I", 1))
		return 0;	/* Device idle */
	else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) {
		bitforce->hw_errors++;
		applog(LOG_WARNING, "BFL%i: Error: Get result reports: %s", bitforce->device_id, pdevbuf);
		bitforce_clear_buffer(bitforce);
		return 0;
	}

	pnoncebuf = &pdevbuf[12];

	while (1) {
		hex2bin((void*)&nonce, pnoncebuf, 4);
#ifndef __BIG_ENDIAN__
		nonce = swab32(nonce);
#endif
		if (unlikely(bitforce->nonce_range && (nonce >= work->blk.nonce ||
			(work->blk.nonce > 0 && nonce < work->blk.nonce - bitforce->nonces - 1)))) {
				applog(LOG_WARNING, "BFL%i: Disabling broken nonce range support", bitforce->device_id);
				bitforce->nonce_range = false;
				work->blk.nonce = 0xffffffff;
				bitforce->sleep_ms *= 5;
				bitforce->kname = KNAME_WORK;
		}
			
		submit_nonce(thr, work, nonce);
		if (strncmp(&pnoncebuf[8], ",", 1))
			break;
		pnoncebuf += 9;
	}

	return bitforce->nonces;
}
Beispiel #5
0
static bool bitforce_send_work(struct thr_info *thr, struct work *work)
{
	struct cgpu_info *bitforce = thr->cgpu;
	int fdDev = bitforce->device_fd;
	unsigned char ob[70];
	char pdevbuf[0x100];
	char *s;

	if (!fdDev)
		return false;
re_send:
	mutex_lock(&bitforce->device_mutex);
	if (bitforce->nonce_range)
		BFwrite(fdDev, "ZPX", 3);
	else
		BFwrite(fdDev, "ZDX", 3);
	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
	if (!pdevbuf[0] || !strncasecmp(pdevbuf, "B", 1)) {
		mutex_unlock(&bitforce->device_mutex);
		nmsleep(WORK_CHECK_INTERVAL_MS);
		goto re_send;
	} else if (unlikely(strncasecmp(pdevbuf, "OK", 2))) {
		mutex_unlock(&bitforce->device_mutex);
		if (bitforce->nonce_range) {
			applog(LOG_WARNING, "BFL%i: Does not support nonce range, disabling", bitforce->device_id);
			bitforce->nonce_range = false;
			bitforce->sleep_ms *= 5;
			bitforce->kname = KNAME_WORK;
			goto re_send;
		}
		applog(LOG_ERR, "BFL%i: Error: Send work reports: %s", bitforce->device_id, pdevbuf);
		return false;
	}

	sprintf((char *)ob, ">>>>>>>>");
	memcpy(ob + 8, work->midstate, 32);
	memcpy(ob + 8 + 32, work->data + 64, 12);
	if (!bitforce->nonce_range) {
		sprintf((char *)ob + 8 + 32 + 12, ">>>>>>>>");
		work->blk.nonce = bitforce->nonces = 0xffffffff;
		BFwrite(fdDev, ob, 60);
	} else {
		uint32_t *nonce;

		nonce = (uint32_t *)(ob + 8 + 32 + 12);
		*nonce = htobe32(work->blk.nonce);
		nonce = (uint32_t *)(ob + 8 + 32 + 12 + 4);
		/* Split work up into 1/5th nonce ranges */
		bitforce->nonces = 0x33333332;
		*nonce = htobe32(work->blk.nonce + bitforce->nonces);
		work->blk.nonce += bitforce->nonces + 1;
		sprintf((char *)ob + 8 + 32 + 12 + 8, ">>>>>>>>");
		BFwrite(fdDev, ob, 68);
	}

	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
	mutex_unlock(&bitforce->device_mutex);

	if (opt_debug) {
		s = bin2hex(ob + 8, 44);
		applog(LOG_DEBUG, "BFL%i: block data: %s", bitforce->device_id, s);
		free(s);
	}

	if (unlikely(!pdevbuf[0])) {
		applog(LOG_ERR, "BFL%i: Error: Send block data returned empty string/timed out", bitforce->device_id);
		return false;
	}

	if (unlikely(strncasecmp(pdevbuf, "OK", 2))) {
		applog(LOG_ERR, "BFL%i: Error: Send block data reports: %s", bitforce->device_id, pdevbuf);
		return false;
	}

	gettimeofday(&bitforce->work_start_tv, NULL);
	return true;
}
Beispiel #6
0
static bool bitforce_send_work(struct thr_info *thr, struct work *work)
{
	struct cgpu_info *bitforce = thr->cgpu;
	unsigned char ob[70];
	char buf[BITFORCE_BUFSIZ+1];
	int err, amount;
	char *s;
	char *cmd;
	int len;

re_send:
	if (bitforce->nonce_range) {
		cmd = BITFORCE_SENDRANGE;
		len = BITFORCE_SENDRANGE_LEN;
	} else {
		cmd = BITFORCE_SENDWORK;
		len = BITFORCE_SENDWORK_LEN;
	}

	mutex_lock(&bitforce->device_mutex);
	if ((err = usb_write(bitforce, cmd, len, &amount, C_REQUESTSENDWORK)) < 0 || amount != len) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "%s%i: request send work failed (%d:%d)",
				bitforce->drv->name, bitforce->device_id, amount, err);
		return false;
	}

	if ((err = usb_ftdi_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_REQUESTSENDWORKSTATUS)) < 0) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "%s%d: read request send work status failed (%d:%d)",
				bitforce->drv->name, bitforce->device_id, amount, err);
		return false;
	}

	if (amount == 0 || !buf[0] || !strncasecmp(buf, "B", 1)) {
		mutex_unlock(&bitforce->device_mutex);
		nmsleep(WORK_CHECK_INTERVAL_MS);
		goto re_send;
	} else if (unlikely(strncasecmp(buf, "OK", 2))) {
		mutex_unlock(&bitforce->device_mutex);
		if (bitforce->nonce_range) {
			applog(LOG_WARNING, "%s%i: Does not support nonce range, disabling",
						bitforce->drv->name, bitforce->device_id);
			bitforce->nonce_range = false;
			bitforce->sleep_ms *= 5;
			bitforce->kname = KNAME_WORK;
			goto re_send;
		}
		applog(LOG_ERR, "%s%i: Error: Send work reports: %s",
				bitforce->drv->name, bitforce->device_id, buf);
		return false;
	}

	sprintf((char *)ob, ">>>>>>>>");
	memcpy(ob + 8, work->midstate, 32);
	memcpy(ob + 8 + 32, work->data + 64, 12);
	if (!bitforce->nonce_range) {
		sprintf((char *)ob + 8 + 32 + 12, ">>>>>>>>");
		work->blk.nonce = bitforce->nonces = 0xffffffff;
		len = 60;
	} else {
		uint32_t *nonce;

		nonce = (uint32_t *)(ob + 8 + 32 + 12);
		*nonce = htobe32(work->blk.nonce);
		nonce = (uint32_t *)(ob + 8 + 32 + 12 + 4);
		/* Split work up into 1/5th nonce ranges */
		bitforce->nonces = 0x33333332;
		*nonce = htobe32(work->blk.nonce + bitforce->nonces);
		work->blk.nonce += bitforce->nonces + 1;
		sprintf((char *)ob + 8 + 32 + 12 + 8, ">>>>>>>>");
		len = 68;
	}

	if ((err = usb_write(bitforce, (char *)ob, len, &amount, C_SENDWORK)) < 0 || amount != len) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "%s%i: send work failed (%d:%d)",
				bitforce->drv->name, bitforce->device_id, amount, err);
		return false;
	}

	if ((err = usb_ftdi_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_SENDWORKSTATUS)) < 0) {
		mutex_unlock(&bitforce->device_mutex);
		applog(LOG_ERR, "%s%d: read send work status failed (%d:%d)",
				bitforce->drv->name, bitforce->device_id, amount, err);
		return false;
	}

	mutex_unlock(&bitforce->device_mutex);

	if (opt_debug) {
		s = bin2hex(ob + 8, 44);
		applog(LOG_DEBUG, "%s%i: block data: %s",
				bitforce->drv->name, bitforce->device_id, s);
		free(s);
	}

	if (amount == 0 || !buf[0]) {
		applog(LOG_ERR, "%s%i: Error: Send block data returned empty string/timed out",
				bitforce->drv->name, bitforce->device_id);
		return false;
	}

	if (unlikely(strncasecmp(buf, "OK", 2))) {
		applog(LOG_ERR, "%s%i: Error: Send block data reports: %s",
				bitforce->drv->name, bitforce->device_id, buf);
		return false;
	}

	gettimeofday(&bitforce->work_start_tv, NULL);
	return true;
}
Beispiel #7
0
static bool bitforce_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
{
	char buf[BITFORCE_BUFSIZ+1];
	char devpath[20];
	int err, amount;
	char *s;

	struct cgpu_info *bitforce = NULL;
	bitforce = calloc(1, sizeof(*bitforce));
	bitforce->drv = &bitforce_drv;
	bitforce->deven = DEV_ENABLED;
	bitforce->threads = 1;

	if (!usb_init(bitforce, dev, found)) {
		applog(LOG_ERR, "%s detect (%d:%d) failed to initialise (incorrect device?)",
			bitforce->drv->dname,
			(int)libusb_get_bus_number(dev),
			(int)libusb_get_device_address(dev));
		goto shin;
	}

	sprintf(devpath, "%d:%d",
			(int)(bitforce->usbdev->bus_number),
			(int)(bitforce->usbdev->device_address));

	int init_count = 0;
reinit:

	bitforce_initialise(bitforce, false);

	if ((err = usb_write(bitforce, BITFORCE_IDENTIFY, BITFORCE_IDENTIFY_LEN, &amount, C_REQUESTIDENTIFY)) < 0 || amount != BITFORCE_IDENTIFY_LEN) {
		applog(LOG_ERR, "%s detect (%s) send identify request failed (%d:%d)",
			bitforce->drv->dname, devpath, amount, err);
		goto unshin;
	}

	if ((err = usb_ftdi_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_GETIDENTIFY)) < 0 || amount < 1) {
		// Maybe it was still processing previous work?
		if (++init_count <= REINIT_COUNT) {
			if (init_count < 2) {
				applog(LOG_WARNING, "%s detect (%s) 1st init failed - retrying (%d:%d)",
					bitforce->drv->dname, devpath, amount, err);
			}
			nmsleep(REINIT_TIME_MS);
			goto reinit;
		}

		if (init_count > 0)
			applog(LOG_WARNING, "%s detect (%s) init failed %d times",
				bitforce->drv->dname, devpath, init_count);

		if (err < 0) {
			applog(LOG_ERR, "%s detect (%s) error identify reply (%d:%d)",
				bitforce->drv->dname, devpath, amount, err);
		} else {
			applog(LOG_ERR, "%s detect (%s) empty identify reply (%d)",
				bitforce->drv->dname, devpath, amount);
		}

		goto unshin;
	}
	buf[amount] = '\0';

	if (unlikely(!strstr(buf, "SHA256"))) {
		applog(LOG_ERR, "%s detect (%s) didn't recognise '%s'",
			bitforce->drv->dname, devpath, buf);
		goto unshin;
	}

	if (likely((!memcmp(buf, ">>>ID: ", 7)) && (s = strstr(buf + 3, ">>>")))) {
		s[0] = '\0';
		bitforce->name = strdup(buf + 7);
	} else {
		bitforce->name = (char *)blank;
	}

	// We have a real BitForce!
	applog(LOG_DEBUG, "%s (%s) identified as: '%s'",
		bitforce->drv->dname, devpath, bitforce->name);

	/* Initially enable support for nonce range and disable it later if it
	 * fails */
	if (opt_bfl_noncerange) {
		bitforce->nonce_range = true;
		bitforce->sleep_ms = BITFORCE_SLEEP_MS;
		bitforce->kname = KNAME_RANGE;
	} else {
		bitforce->sleep_ms = BITFORCE_SLEEP_MS * 5;
		bitforce->kname = KNAME_WORK;
	}

	bitforce->device_path = strdup(devpath);

	if (!add_cgpu(bitforce))
		goto unshin;

	update_usb_stats(bitforce);

	mutex_init(&bitforce->device_mutex);

	return true;

unshin:

	usb_uninit(bitforce);

shin:

	free(bitforce->device_path);

	if (bitforce->name != blank)
		free(bitforce->name);

	free(bitforce);

	return false;
}
Beispiel #8
0
static bool ztex_checkNonce(struct libztex_device *ztex,
                            struct work *work,
                            struct libztex_hash_data *hdata)
{
	uint32_t *data32 = (uint32_t *)(work->data);
	unsigned char swap[80];
	uint32_t *swap32 = (uint32_t *)swap;
	unsigned char hash1[32];
	unsigned char hash2[32];
	uint32_t *hash2_32 = (uint32_t *)hash2;
	int i;

#if defined(__BIGENDIAN__) || defined(MIPSEB)
	hdata->nonce = swab32(hdata->nonce);
	hdata->hash7 = swab32(hdata->hash7);
#endif

	work->data[64 + 12 + 0] = (hdata->nonce >> 0) & 0xff;
	work->data[64 + 12 + 1] = (hdata->nonce >> 8) & 0xff;
	work->data[64 + 12 + 2] = (hdata->nonce >> 16) & 0xff;
	work->data[64 + 12 + 3] = (hdata->nonce >> 24) & 0xff;

	for (i = 0; i < 80 / 4; i++)
		swap32[i] = swab32(data32[i]);

	sha2(swap, 80, hash1, false);
	sha2(hash1, 32, hash2, false);
#if defined(__BIGENDIAN__) || defined(MIPSEB)
	if (hash2_32[7] != ((hdata->hash7 + 0x5be0cd19) & 0xFFFFFFFF)) {
#else
	if (swab32(hash2_32[7]) != ((hdata->hash7 + 0x5be0cd19) & 0xFFFFFFFF)) {
#endif
		ztex->errorCount[ztex->freqM] += 1.0 / ztex->numNonces;
		applog(LOG_DEBUG, "%s: checkNonce failed for %0.8X", ztex->repr, hdata->nonce);
		return false;
	}
	return true;
}

static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
                              __maybe_unused int64_t max_nonce)
{
	struct libztex_device *ztex;
	unsigned char sendbuf[44];
	int i, j, k;
	uint32_t *backlog;
	int backlog_p = 0, backlog_max;
	uint32_t *lastnonce;
	uint32_t nonce, noncecnt = 0;
	bool overflow, found;
	struct libztex_hash_data hdata[GOLDEN_BACKLOG];

	if (thr->cgpu->deven == DEV_DISABLED)
		return -1;

	ztex = thr->cgpu->device_ztex;

	memcpy(sendbuf, work->data + 64, 12);
	memcpy(sendbuf + 12, work->midstate, 32);

	ztex_selectFpga(ztex);
	i = libztex_sendHashData(ztex, sendbuf);
	if (i < 0) {
		// Something wrong happened in send
		applog(LOG_ERR, "%s: Failed to send hash data with err %d, retrying", ztex->repr, i);
		nmsleep(500);
		i = libztex_sendHashData(ztex, sendbuf);
		if (i < 0) {
			// And there's nothing we can do about it
			ztex_disable(thr);
			applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i);
			ztex_releaseFpga(ztex);
			return -1;
		}
	}
	ztex_releaseFpga(ztex);

	applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr);

	lastnonce = calloc(1, sizeof(uint32_t)*ztex->numNonces);
	if (lastnonce == NULL) {
		applog(LOG_ERR, "%s: failed to allocate lastnonce[%d]", ztex->repr, ztex->numNonces);
		return -1;
	}

	/* Add an extra slot for detecting dupes that lie around */
	backlog_max = ztex->numNonces * (2 + ztex->extraSolutions);
	backlog = calloc(1, sizeof(uint32_t) * backlog_max);
	if (backlog == NULL) {
		applog(LOG_ERR, "%s: failed to allocate backlog[%d]", ztex->repr, backlog_max);
		return -1;
	}

	overflow = false;

	applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr);
	while (!(overflow || thr->work_restart)) {
		nmsleep(250);
		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}
		ztex_selectFpga(ztex);
		i = libztex_readHashData(ztex, &hdata[0]);
		if (i < 0) {
			// Something wrong happened in read
			applog(LOG_ERR, "%s: Failed to read hash data with err %d, retrying", ztex->repr, i);
			nmsleep(500);
			i = libztex_readHashData(ztex, &hdata[0]);
			if (i < 0) {
				// And there's nothing we can do about it
				ztex_disable(thr);
				applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
				free(lastnonce);
				free(backlog);
				ztex_releaseFpga(ztex);
				return -1;
			}
		}
		ztex_releaseFpga(ztex);

		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}

		ztex->errorCount[ztex->freqM] *= 0.995;
		ztex->errorWeight[ztex->freqM] = ztex->errorWeight[ztex->freqM] * 0.995 + 1.0;
 
		for (i = 0; i < ztex->numNonces; i++) {
			nonce = hdata[i].nonce;
#if defined(__BIGENDIAN__) || defined(MIPSEB)
			nonce = swab32(nonce);
#endif
			if (nonce > noncecnt)
				noncecnt = nonce;
			if (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) {
				applog(LOG_DEBUG, "%s: overflow nonce=%0.8x lastnonce=%0.8x", ztex->repr, nonce, lastnonce[i]);
				overflow = true;
			} else
				lastnonce[i] = nonce;
#if !(defined(__BIGENDIAN__) || defined(MIPSEB))
			nonce = swab32(nonce);
#endif
			if (!ztex_checkNonce(ztex, work, &hdata[i])) {
				thr->cgpu->hw_errors++;
				continue;
			}
			for (j=0; j<=ztex->extraSolutions; j++) {
				nonce = hdata[i].goldenNonce[j];
				if (nonce > 0) {
					found = false;
					for (k = 0; k < backlog_max; k++) {
						if (backlog[k] == nonce) {
							found = true;
							break;
						}
					}
					if (!found) {
						applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j);
						backlog[backlog_p++] = nonce;
						if (backlog_p >= backlog_max)
							backlog_p = 0;
#if defined(__BIGENDIAN__) || defined(MIPSEB)
						nonce = swab32(nonce);
#endif
						work->blk.nonce = 0xffffffff;
						submit_nonce(thr, work, nonce);
						applog(LOG_DEBUG, "%s: submitted %0.8x", ztex->repr, nonce);
					}
				}
			}
		}
	}

	ztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] /	ztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0);
	if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])
		ztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM];

	if (!ztex_updateFreq(ztex)) {
		// Something really serious happened, so mark this thread as dead!
		free(lastnonce);
		free(backlog);
		
		return -1;
	}

	applog(LOG_DEBUG, "%s: exit %1.8X", ztex->repr, noncecnt);

	work->blk.nonce = 0xffffffff;

	free(lastnonce);
	free(backlog);

	return noncecnt;
}

static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
{
	if (cgpu->deven == DEV_ENABLED) {
		tailsprintf(buf, "%s-%d | ", cgpu->device_ztex->snString, cgpu->device_ztex->fpgaNum+1);
		tailsprintf(buf, "%0.1fMHz | ", cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1));
	}
}

static bool ztex_prepare(struct thr_info *thr)
{
	struct timeval now;
	struct cgpu_info *cgpu = thr->cgpu;
	struct libztex_device *ztex = cgpu->device_ztex;

	gettimeofday(&now, NULL);
	get_datestamp(cgpu->init, &now);

	ztex_selectFpga(ztex);
	if (libztex_configureFpga(ztex) != 0) {
		libztex_resetFpga(ztex);
		ztex_releaseFpga(ztex);
		applog(LOG_ERR, "%s: Disabling!", thr->cgpu->device_ztex->repr);
		thr->cgpu->deven = DEV_DISABLED;
		return true;
	}
	ztex->freqM = ztex->freqMaxM+1;;
	//ztex_updateFreq(ztex);
	libztex_setFreq(ztex, ztex->freqMDefault);
	ztex_releaseFpga(ztex);
	applog(LOG_DEBUG, "%s: prepare", ztex->repr);
	return true;
}

static void ztex_shutdown(struct thr_info *thr)
{
	if (thr->cgpu->device_ztex != NULL) {
		if (thr->cgpu->device_ztex->fpgaNum == 0)
			pthread_mutex_destroy(&thr->cgpu->device_ztex->mutex);  
		applog(LOG_DEBUG, "%s: shutdown", thr->cgpu->device_ztex->repr);
		libztex_destroy_device(thr->cgpu->device_ztex);
		thr->cgpu->device_ztex = NULL;
	}
}

static void ztex_disable(struct thr_info *thr)
{
	applog(LOG_ERR, "%s: Disabling!", thr->cgpu->device_ztex->repr);
	devices[thr->cgpu->device_id]->deven = DEV_DISABLED;
	ztex_shutdown(thr);
}
static int64_t bitforce_get_result(struct thr_info *thr, struct work *work)
{
	struct cgpu_info *bitforce = thr->cgpu;
	unsigned int delay_time_ms;
	struct timeval elapsed;
	struct timeval now;
	char buf[BITFORCE_BUFSIZ+1];
	int amount;
	char *pnoncebuf;
	uint32_t nonce;

	while (1) {
		if (unlikely(thr->work_restart))
			return 0;

		mutex_lock(&bitforce->device_mutex);
		usb_write(bitforce, BITFORCE_WORKSTATUS, BITFORCE_WORKSTATUS_LEN, &amount, C_REQUESTWORKSTATUS);
		usb_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_GETWORKSTATUS);
		mutex_unlock(&bitforce->device_mutex);

		cgtime(&now);
		timersub(&now, &bitforce->work_start_tv, &elapsed);

		if (elapsed.tv_sec >= BITFORCE_LONG_TIMEOUT_S) {
			applog(LOG_ERR, "%s%i: took %ldms - longer than %dms",
				bitforce->drv->name, bitforce->device_id,
				tv_to_ms(elapsed), BITFORCE_LONG_TIMEOUT_MS);
			return 0;
		}

		if (amount > 0 && buf[0] && strncasecmp(buf, "B", 1)) /* BFL does not respond during throttling */
			break;

		/* if BFL is throttling, no point checking so quickly */
		delay_time_ms = (buf[0] ? BITFORCE_CHECK_INTERVAL_MS : 2 * WORK_CHECK_INTERVAL_MS);
		nmsleep(delay_time_ms);
		bitforce->wait_ms += delay_time_ms;
	}

	if (elapsed.tv_sec > BITFORCE_TIMEOUT_S) {
		applog(LOG_ERR, "%s%i: took %ldms - longer than %dms",
			bitforce->drv->name, bitforce->device_id,
			tv_to_ms(elapsed), BITFORCE_TIMEOUT_MS);
		dev_error(bitforce, REASON_DEV_OVER_HEAT);

		/* Only return if we got nothing after timeout - there still may be results */
		if (amount == 0)
			return 0;
	} else if (!strncasecmp(buf, BITFORCE_EITHER, BITFORCE_EITHER_LEN)) {
		/* Simple timing adjustment. Allow a few polls to cope with
		 * OS timer delays being variably reliable. wait_ms will
		 * always equal sleep_ms when we've waited greater than or
		 * equal to the result return time.*/
		delay_time_ms = bitforce->sleep_ms;

		if (bitforce->wait_ms > bitforce->sleep_ms + (WORK_CHECK_INTERVAL_MS * 2))
			bitforce->sleep_ms += (bitforce->wait_ms - bitforce->sleep_ms) / 2;
		else if (bitforce->wait_ms == bitforce->sleep_ms) {
			if (bitforce->sleep_ms > WORK_CHECK_INTERVAL_MS)
				bitforce->sleep_ms -= WORK_CHECK_INTERVAL_MS;
			else if (bitforce->sleep_ms > BITFORCE_CHECK_INTERVAL_MS)
				bitforce->sleep_ms -= BITFORCE_CHECK_INTERVAL_MS;
		}

		if (delay_time_ms != bitforce->sleep_ms)
			  applog(LOG_DEBUG, "%s%i: Wait time changed to: %d, waited %u",
					bitforce->drv->name, bitforce->device_id,
					bitforce->sleep_ms, bitforce->wait_ms);

		/* Work out the average time taken. Float for calculation, uint for display */
		bitforce->avg_wait_f += (tv_to_ms(elapsed) - bitforce->avg_wait_f) / TIME_AVG_CONSTANT;
		bitforce->avg_wait_d = (unsigned int) (bitforce->avg_wait_f + 0.5);
	}

	applog(LOG_DEBUG, "%s%i: waited %dms until %s",
			bitforce->drv->name, bitforce->device_id,
			bitforce->wait_ms, buf);
	if (!strncasecmp(buf, BITFORCE_NO_NONCE, BITFORCE_NO_NONCE_MATCH))
		return bitforce->nonces;   /* No valid nonce found */
	else if (!strncasecmp(buf, BITFORCE_IDLE, BITFORCE_IDLE_MATCH))
		return 0;	/* Device idle */
	else if (strncasecmp(buf, BITFORCE_NONCE, BITFORCE_NONCE_LEN)) {
		bitforce->hw_errors++;
		applog(LOG_WARNING, "%s%i: Error: Get result reports: %s",
			bitforce->drv->name, bitforce->device_id, buf);
		bitforce_initialise(bitforce, true);
		return 0;
	}

	pnoncebuf = &buf[12];

	while (1) {
		hex2bin((void*)&nonce, pnoncebuf, 4);
#ifndef __BIG_ENDIAN__
		nonce = swab32(nonce);
#endif
		if (unlikely(bitforce->nonce_range && (nonce >= work->blk.nonce ||
			(work->blk.nonce > 0 && nonce < work->blk.nonce - bitforce->nonces - 1)))) {
				applog(LOG_WARNING, "%s%i: Disabling broken nonce range support",
					bitforce->drv->name, bitforce->device_id);
				bitforce->nonce_range = false;
				work->blk.nonce = 0xffffffff;
				bitforce->sleep_ms *= 5;
				bitforce->kname = KNAME_WORK;
		}
			
		submit_nonce(thr, work, nonce);
		if (strncmp(&pnoncebuf[8], ",", 1))
			break;
		pnoncebuf += 9;
	}

	return bitforce->nonces;
}
Beispiel #10
0
static bool bitforce_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
{
	char buf[BITFORCE_BUFSIZ+1];
	int err, amount;
	char *s;
	struct timeval init_start, init_now;
	int init_sleep, init_count;
	bool ident_first;

	struct cgpu_info *bitforce = usb_alloc_cgpu(&bitforce_drv, 1);

	if (!usb_init(bitforce, dev, found))
		goto shin;

	// Allow 2 complete attempts if the 1st time returns an unrecognised reply
	ident_first = true;
retry:
	init_count = 0;
	init_sleep = REINIT_TIME_FIRST_MS;
	cgtime(&init_start);
reinit:
	bitforce_initialise(bitforce, false);
	if ((err = usb_write(bitforce, BITFORCE_IDENTIFY, BITFORCE_IDENTIFY_LEN, &amount, C_REQUESTIDENTIFY)) < 0 || amount != BITFORCE_IDENTIFY_LEN) {
		applog(LOG_ERR, "%s detect (%s) send identify request failed (%d:%d)",
			bitforce->drv->dname, bitforce->device_path, amount, err);
		goto unshin;
	}

	if ((err = usb_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_GETIDENTIFY)) < 0 || amount < 1) {
		init_count++;
		cgtime(&init_now);
		if (us_tdiff(&init_now, &init_start) <= REINIT_TIME_MAX) {
			if (init_count == 2) {
				applog(LOG_WARNING, "%s detect (%s) 2nd init failed (%d:%d) - retrying",
					bitforce->drv->dname, bitforce->device_path, amount, err);
			}
			nmsleep(init_sleep);
			if ((init_sleep * 2) <= REINIT_TIME_MAX_MS)
				init_sleep *= 2;
			goto reinit;
		}

		if (init_count > 0)
			applog(LOG_WARNING, "%s detect (%s) init failed %d times %.2fs",
				bitforce->drv->dname, bitforce->device_path, init_count, tdiff(&init_now, &init_start));

		if (err < 0) {
			applog(LOG_ERR, "%s detect (%s) error identify reply (%d:%d)",
				bitforce->drv->dname, bitforce->device_path, amount, err);
		} else {
			applog(LOG_ERR, "%s detect (%s) empty identify reply (%d)",
				bitforce->drv->dname, bitforce->device_path, amount);
		}

		goto unshin;
	}
	buf[amount] = '\0';

	if (unlikely(!strstr(buf, "SHA256"))) {
		if (ident_first) {
			applog(LOG_WARNING, "%s detect (%s) didn't recognise '%s' trying again ...",
				bitforce->drv->dname, bitforce->device_path, buf);
			ident_first = false;
			goto retry;
		}
		applog(LOG_ERR, "%s detect (%s) didn't recognise '%s' on 2nd attempt",
			bitforce->drv->dname, bitforce->device_path, buf);
		goto unshin;
	}

	if (strstr(buf, "SHA256 SC")) {
#ifdef USE_BFLSC
		applog(LOG_DEBUG, "SC device detected, will defer to BFLSC driver");
#else
		applog(LOG_WARNING, "SC device detected but no BFLSC support compiled in!");
#endif
		goto unshin;
	}

	if (likely((!memcmp(buf, ">>>ID: ", 7)) && (s = strstr(buf + 3, ">>>")))) {
		s[0] = '\0';
		bitforce->name = strdup(buf + 7);
	} else {
		bitforce->name = (char *)blank;
	}

	// We have a real BitForce!
	applog(LOG_DEBUG, "%s (%s) identified as: '%s'",
		bitforce->drv->dname, bitforce->device_path, bitforce->name);

	/* Initially enable support for nonce range and disable it later if it
	 * fails */
	if (opt_bfl_noncerange) {
		bitforce->nonce_range = true;
		bitforce->sleep_ms = BITFORCE_SLEEP_MS;
		bitforce->kname = KNAME_RANGE;
	} else {
		bitforce->sleep_ms = BITFORCE_SLEEP_MS * 5;
		bitforce->kname = KNAME_WORK;
	}

	if (!add_cgpu(bitforce))
		goto unshin;

	update_usb_stats(bitforce);

	mutex_init(&bitforce->device_mutex);

	return true;

unshin:

	usb_uninit(bitforce);

shin:

	if (bitforce->name != blank) {
		free(bitforce->name);
		bitforce->name = NULL;
	}

	bitforce = usb_free_cgpu(bitforce);

	return false;
}
static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
                              __maybe_unused int64_t max_nonce)
{
	struct libztex_device *ztex;
	unsigned char sendbuf[44];
	int i, j, k;
	uint32_t *backlog;
	int backlog_p = 0, backlog_max;
	uint32_t *lastnonce;
	uint32_t nonce, noncecnt = 0;
	bool overflow, found;
	struct libztex_hash_data hdata[GOLDEN_BACKLOG];

	if (thr->cgpu->deven == DEV_DISABLED)
		return -1;

	ztex = thr->cgpu->device_ztex;

	memcpy(sendbuf, work->data + 64, 12);
	memcpy(sendbuf + 12, work->midstate, 32);

	ztex_selectFpga(ztex);
	i = libztex_sendHashData(ztex, sendbuf);
	if (i < 0) {
		// Something wrong happened in send
		applog(LOG_ERR, "%s: Failed to send hash data with err %d, retrying", ztex->repr, i);
		nmsleep(500);
		i = libztex_sendHashData(ztex, sendbuf);
		if (i < 0) {
			// And there's nothing we can do about it
			ztex_disable(thr);
			applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i);
			ztex_releaseFpga(ztex);
			return -1;
		}
	}
	ztex_releaseFpga(ztex);

	applog(LOG_DEBUG, "%s: sent hashdata", ztex->repr);

	lastnonce = calloc(1, sizeof(uint32_t)*ztex->numNonces);
	if (lastnonce == NULL) {
		applog(LOG_ERR, "%s: failed to allocate lastnonce[%d]", ztex->repr, ztex->numNonces);
		return -1;
	}

	/* Add an extra slot for detecting dupes that lie around */
	backlog_max = ztex->numNonces * (2 + ztex->extraSolutions);
	backlog = calloc(1, sizeof(uint32_t) * backlog_max);
	if (backlog == NULL) {
		applog(LOG_ERR, "%s: failed to allocate backlog[%d]", ztex->repr, backlog_max);
		return -1;
	}

	overflow = false;
	int count = 0;
	int validNonces = 0;
	double errorCount = 0;

	applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr);
	while (!(overflow || thr->work_restart)) {
		count++;

		int sleepcount = 0;
		while (thr->work_restart == 0 && sleepcount < 25) {
			nmsleep(10);
			sleepcount += 1;
		}

		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}

		ztex_selectFpga(ztex);
		i = libztex_readHashData(ztex, &hdata[0]);
		if (i < 0) {
			// Something wrong happened in read
			applog(LOG_ERR, "%s: Failed to read hash data with err %d, retrying", ztex->repr, i);
			nmsleep(500);
			i = libztex_readHashData(ztex, &hdata[0]);
			if (i < 0) {
				// And there's nothing we can do about it
				ztex_disable(thr);
				applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
				free(lastnonce);
				free(backlog);
				ztex_releaseFpga(ztex);
				return -1;
			}
		}
		ztex_releaseFpga(ztex);

		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}

		ztex->errorCount[ztex->freqM] *= 0.995;
		ztex->errorWeight[ztex->freqM] = ztex->errorWeight[ztex->freqM] * 0.995 + 1.0;

		for (i = 0; i < ztex->numNonces; i++) {
			nonce = hdata[i].nonce;
			if (nonce > noncecnt)
				noncecnt = nonce;
			if (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) {
				applog(LOG_DEBUG, "%s: overflow nonce=%0.8x lastnonce=%0.8x", ztex->repr, nonce, lastnonce[i]);
				overflow = true;
			} else
				lastnonce[i] = nonce;

			if (ztex_checkNonce(work, nonce) != (hdata->hash7 + 0x5be0cd19)) {
				applog(LOG_DEBUG, "%s: checkNonce failed for %0.8X", ztex->repr, nonce);

				// do not count errors in the first 500ms after sendHashData (2x250 wait time)
				if (count > 2) {
					thr->cgpu->hw_errors++;
					errorCount += (1.0 / ztex->numNonces);
				}
			}
			else
				validNonces++;


			for (j=0; j<=ztex->extraSolutions; j++) {
				nonce = hdata[i].goldenNonce[j];

				if (nonce == ztex->offsNonces) {
					continue;
				}

				// precheck the extraSolutions since they often fail
				if (j > 0 && ztex_checkNonce(work, nonce) != 0) {
					continue;
				}

				found = false;
				for (k = 0; k < backlog_max; k++) {
					if (backlog[k] == nonce) {
						found = true;
						break;
					}
				}
				if (!found) {
					applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j);
					backlog[backlog_p++] = nonce;

					if (backlog_p >= backlog_max)
						backlog_p = 0;

					work->blk.nonce = 0xffffffff;
					submit_nonce(thr, work, nonce);
					applog(LOG_DEBUG, "%s: submitted %0.8x", ztex->repr, nonce);
				}
			}
		}
	}

	// only add the errorCount if we had at least some valid nonces or
	// had no valid nonces in the last round
	if (errorCount > 0.0) {
		if (ztex->nonceCheckValid > 0 && validNonces == 0) {
			applog(LOG_ERR, "%s: resetting %.1f errors", ztex->repr, errorCount);
		}
		else {
			ztex->errorCount[ztex->freqM] += errorCount;
		}
	}

	// remember the number of valid nonces for the check in the next round
	ztex->nonceCheckValid = validNonces;

	ztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] /	ztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0);
	if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])
		ztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM];

	if (!ztex_updateFreq(ztex)) {
		// Something really serious happened, so mark this thread as dead!
		free(lastnonce);
		free(backlog);
		
		return -1;
	}

	applog(LOG_DEBUG, "%s: exit %1.8X", ztex->repr, noncecnt);

	work->blk.nonce = 0xffffffff;

	free(lastnonce);
	free(backlog);

	return noncecnt;
}
Beispiel #12
0
static int64_t bitfury_scanHash(struct thr_info *thr)
{
	static struct bitfury_device *devices; // TODO Move somewhere to appropriate place
	int chip_n;
	int chip;
	uint64_t hashes = 0;
	struct timeval now;
	unsigned char line[2048];
	int short_stat = 10;
	static time_t short_out_t;
	int long_stat = 1800;
	static time_t long_out_t;
	int long_long_stat = 60 * 30;
	static time_t long_long_out_t;
	static first = 0; //TODO Move to detect()
	int i;

	devices = thr->cgpu->devices;
	chip_n = thr->cgpu->chip_n;

	if (!first) {
		for (i = 0; i < chip_n; i++) {
			devices[i].osc6_bits = 54;
		}
		for (i = 0; i < chip_n; i++) {
			send_reinit(devices[i].slot, devices[i].fasync, devices[i].osc6_bits);
		}
	}
	first = 1;

	for (chip = 0; chip < chip_n; chip++) {
		devices[chip].job_switched = 0;
		if(!devices[chip].work) {
			devices[chip].work = get_queued(thr->cgpu);
			if (devices[chip].work == NULL) {
				return 0;
			}
			work_to_payload(&(devices[chip].payload), devices[chip].work);
		}
	}

	libbitfury_sendHashData(devices, chip_n);
	nmsleep(5);

	cgtime(&now);
	chip = 0;
	for (;chip < chip_n; chip++) {
		if (devices[chip].job_switched) {
			int i,j;
			int *res = devices[chip].results;
			struct work *work = devices[chip].work;
			struct work *owork = devices[chip].owork;
			struct work *o2work = devices[chip].o2work;
			i = devices[chip].results_n;
			for (j = i - 1; j >= 0; j--) {
				if (owork) {
					submit_nonce(thr, owork, bswap_32(res[j]));
					devices[chip].stat_ts[devices[chip].stat_counter++] =
						now.tv_sec;
					if (devices[chip].stat_counter == BITFURY_STAT_N) {
						devices[chip].stat_counter = 0;
					}
				}
				if (o2work) {
					// TEST
					//submit_nonce(thr, owork, bswap_32(res[j]));
				}
			}
			devices[chip].results_n = 0;
			devices[chip].job_switched = 0;
			if (devices[chip].old_nonce && o2work) {
					submit_nonce(thr, o2work, bswap_32(devices[chip].old_nonce));
					i++;
			}
			if (devices[chip].future_nonce) {
					submit_nonce(thr, work, bswap_32(devices[chip].future_nonce));
					i++;
			}

			if (o2work)
				work_completed(thr->cgpu, o2work);

			devices[chip].o2work = devices[chip].owork;
			devices[chip].owork = devices[chip].work;
			devices[chip].work = NULL;
			hashes += 0xffffffffull * i;
		}
	}

	if (now.tv_sec - short_out_t > short_stat) {
		int shares_first = 0, shares_last = 0, shares_total = 0;
		char stat_lines[32][256] = {0};
		int len, k;
		double gh[32][8] = {0};
		double ghsum = 0, gh1h = 0, gh2h = 0;
		unsigned strange_counter = 0;

		for (chip = 0; chip < chip_n; chip++) {
			int shares_found = calc_stat(devices[chip].stat_ts, short_stat, now);
			double ghash;
			len = strlen(stat_lines[devices[chip].slot]);
			ghash = shares_to_ghashes(shares_found, short_stat);
			gh[devices[chip].slot][chip & 0x07] = ghash;
			snprintf(stat_lines[devices[chip].slot] + len, 256 - len, "%.1f-%3.0f ", ghash, devices[chip].mhz);

			if(short_out_t && ghash < 0.5) {
				applog(LOG_WARNING, "Chip_id %d FREQ CHANGE\n", chip);
				send_freq(devices[chip].slot, devices[chip].fasync, devices[chip].osc6_bits - 1);
				nmsleep(1);
				send_freq(devices[chip].slot, devices[chip].fasync, devices[chip].osc6_bits);
			}
			shares_total += shares_found;
			shares_first += chip < 4 ? shares_found : 0;
			shares_last += chip > 3 ? shares_found : 0;
			strange_counter += devices[chip].strange_counter;
			devices[chip].strange_counter = 0;
		}
		sprintf(line, "vvvvwww SHORT stat %ds: wwwvvvv", short_stat);
		applog(LOG_WARNING, line);
		sprintf(line, "stranges: %u", strange_counter);
		applog(LOG_WARNING, line);
		for(i = 0; i < 32; i++)
			if(strlen(stat_lines[i])) {
				len = strlen(stat_lines[i]);
				ghsum = 0;
				gh1h = 0;
				gh2h = 0;
				for(k = 0; k < 4; k++) {
					gh1h += gh[i][k];
					gh2h += gh[i][k+4];
					ghsum += gh[i][k] + gh[i][k+4];
				}
				snprintf(stat_lines[i] + len, 256 - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
				applog(LOG_WARNING, stat_lines[i]);
			}
		short_out_t = now.tv_sec;
	}

	if (now.tv_sec - long_out_t > long_stat) {
		int shares_first = 0, shares_last = 0, shares_total = 0;
		char stat_lines[32][256] = {0};
		int len, k;
		double gh[32][8] = {0};
		double ghsum = 0, gh1h = 0, gh2h = 0;

		for (chip = 0; chip < chip_n; chip++) {
			int shares_found = calc_stat(devices[chip].stat_ts, long_stat, now);
			double ghash;
			len = strlen(stat_lines[devices[chip].slot]);
			ghash = shares_to_ghashes(shares_found, long_stat);
			gh[devices[chip].slot][chip & 0x07] = ghash;
			snprintf(stat_lines[devices[chip].slot] + len, 256 - len, "%.1f-%3.0f ", ghash, devices[chip].mhz);

			shares_total += shares_found;
			shares_first += chip < 4 ? shares_found : 0;
			shares_last += chip > 3 ? shares_found : 0;
		}
		sprintf(line, "!!!_________ LONG stat %ds: ___________!!!", long_stat);
		applog(LOG_WARNING, line);
		for(i = 0; i < 32; i++)
			if(strlen(stat_lines[i])) {
				len = strlen(stat_lines[i]);
				ghsum = 0;
				gh1h = 0;
				gh2h = 0;
				for(k = 0; k < 4; k++) {
					gh1h += gh[i][k];
					gh2h += gh[i][k+4];
					ghsum += gh[i][k] + gh[i][k+4];
				}
				snprintf(stat_lines[i] + len, 256 - len, "- %2.1f + %2.1f = %2.1f slot %i ", gh1h, gh2h, ghsum, i);
				applog(LOG_WARNING, stat_lines[i]);
			}
		long_out_t = now.tv_sec;
	}

	return hashes;
}
Beispiel #13
0
static bool bitforce_detect_one(struct libusb_device *dev, struct usb_find_devices *found)
{
    char buf[BITFORCE_BUFSIZ+1];
    char devpath[20];
    int err, amount;
    char *s;
    struct timeval init_start, init_now;
    int init_sleep, init_count;
    bool ident_first;

    struct cgpu_info *bitforce = NULL;
    bitforce = calloc(1, sizeof(*bitforce));
    bitforce->drv = &bitforce_drv;
    bitforce->deven = DEV_ENABLED;
    bitforce->threads = 1;

    if (!usb_init(bitforce, dev, found)) {
        applog(LOG_ERR, "%s detect (%d:%d) failed to initialise (incorrect device?)",
               bitforce->drv->dname,
               (int)(bitforce->usbinfo.bus_number),
               (int)(bitforce->usbinfo.device_address));
        goto shin;
    }

    sprintf(devpath, "%d:%d",
            (int)(bitforce->usbinfo.bus_number),
            (int)(bitforce->usbinfo.device_address));


    // Allow 2 complete attempts if the 1st time returns an unrecognised reply
    ident_first = true;
retry:
    init_count = 0;
    init_sleep = REINIT_TIME_FIRST_MS;
    gettimeofday(&init_start, NULL);
reinit:
    bitforce_initialise(bitforce, false);
    if ((err = usb_write(bitforce, BITFORCE_IDENTIFY, BITFORCE_IDENTIFY_LEN, &amount, C_REQUESTIDENTIFY)) < 0 || amount != BITFORCE_IDENTIFY_LEN) {
        applog(LOG_ERR, "%s detect (%s) send identify request failed (%d:%d)",
               bitforce->drv->dname, devpath, amount, err);
        goto unshin;
    }

    if ((err = usb_ftdi_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_GETIDENTIFY)) < 0 || amount < 1) {
        init_count++;
        gettimeofday(&init_now, NULL);
        if (us_tdiff(&init_now, &init_start) <= REINIT_TIME_MAX) {
            if (init_count == 2) {
                applog(LOG_WARNING, "%s detect (%s) 2nd init failed (%d:%d) - retrying",
                       bitforce->drv->dname, devpath, amount, err);
            }
            nmsleep(init_sleep);
            if ((init_sleep * 2) <= REINIT_TIME_MAX_MS)
                init_sleep *= 2;
            goto reinit;
        }

        if (init_count > 0)
            applog(LOG_WARNING, "%s detect (%s) init failed %d times %.2fs",
                   bitforce->drv->dname, devpath, init_count, tdiff(&init_now, &init_start));

        if (err < 0) {
            applog(LOG_ERR, "%s detect (%s) error identify reply (%d:%d)",
                   bitforce->drv->dname, devpath, amount, err);
        } else {
            applog(LOG_ERR, "%s detect (%s) empty identify reply (%d)",
                   bitforce->drv->dname, devpath, amount);
        }

        goto unshin;
    }
    buf[amount] = '\0';

    if (unlikely(!strstr(buf, "SHA256"))) {
        if (ident_first) {
            applog(LOG_WARNING, "%s detect (%s) didn't recognise '%s' trying again ...",
                   bitforce->drv->dname, devpath, buf);
            ident_first = false;
            goto retry;
        }
        applog(LOG_ERR, "%s detect (%s) didn't recognise '%s' on 2nd attempt",
               bitforce->drv->dname, devpath, buf);
        goto unshin;
    }

    if (likely((!memcmp(buf, ">>>ID: ", 7)) && (s = strstr(buf + 3, ">>>")))) {
        s[0] = '\0';
        bitforce->name = strdup(buf + 7);
    } else {
        bitforce->name = (char *)blank;
    }

    // We have a real BitForce!
    applog(LOG_DEBUG, "%s (%s) identified as: '%s'",
           bitforce->drv->dname, devpath, bitforce->name);

    /* Initially enable support for nonce range and disable it later if it
     * fails */
    if (opt_bfl_noncerange) {
        bitforce->nonce_range = true;
        bitforce->sleep_ms = BITFORCE_SLEEP_MS;
        bitforce->kname = KNAME_RANGE;
    } else {
        bitforce->sleep_ms = BITFORCE_SLEEP_MS * 5;
        bitforce->kname = KNAME_WORK;
    }

    bitforce->device_path = strdup(devpath);

    if (!add_cgpu(bitforce))
        goto unshin;

    update_usb_stats(bitforce);

    mutex_init(&bitforce->device_mutex);

    return true;

unshin:

    usb_uninit(bitforce);

shin:

    free(bitforce->device_path);

    if (bitforce->name != blank)
        free(bitforce->name);

    if (bitforce->drv->copy)
        free(bitforce->drv);

    free(bitforce);

    return false;
}
static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
                              __maybe_unused int64_t max_nonce)
{

	// int numbytes = 80;			// KRAMBLE 80 byte protocol
	int numbytes = 76;				// KRAMBLE 76 byte protocol

	struct libztex_device *ztex;
	unsigned char sendbuf[80];		// KRAMBLE
	int i, j, k;
	uint32_t *backlog;
	int backlog_p = 0, backlog_max;
	uint32_t *lastnonce;
	uint32_t nonce, noncecnt = 0;
	bool overflow, found;
	struct libztex_hash_data hdata[GOLDEN_BACKLOG];

	if (thr->cgpu->deven == DEV_DISABLED)
		return -1;

	ztex = thr->cgpu->device_ztex;

	// memcpy(sendbuf, work->data + 64, 12);
	// memcpy(sendbuf + 12, work->midstate, 32);
	memcpy(sendbuf, work->data, numbytes);	// KRAMBLE

	ztex_selectFpga(ztex);
	i = libztex_sendHashData(ztex, sendbuf, numbytes);
	if (i < 0) {
		// Something wrong happened in send
		applog(LOG_ERR, "%s: Failed to send hash data with err %d, retrying", ztex->repr, i);
		nmsleep(500);
		i = libztex_sendHashData(ztex, sendbuf, numbytes);
		if (i < 0) {
			// And there's nothing we can do about it
			ztex_disable(thr);
			applog(LOG_ERR, "%s: Failed to send hash data with err %d, giving up", ztex->repr, i);
			ztex_releaseFpga(ztex);
			return -1;
		}
	}
	ztex_releaseFpga(ztex);

#if 0	// KRAMBLE
	char *data = bin2hex(work->data, sizeof(work->data));
	applog(LOG_INFO, "%s: sent data %s", ztex->repr, data);
#endif

	lastnonce = calloc(1, sizeof(uint32_t)*ztex->numNonces);
	if (lastnonce == NULL) {
		applog(LOG_ERR, "%s: failed to allocate lastnonce[%d]", ztex->repr, ztex->numNonces);
		return -1;
	}

	/* Add an extra slot for detecting dupes that lie around */
	backlog_max = ztex->numNonces * (2 + ztex->extraSolutions);
	backlog = calloc(1, sizeof(uint32_t) * backlog_max);
	if (backlog == NULL) {
		applog(LOG_ERR, "%s: failed to allocate backlog[%d]", ztex->repr, backlog_max);
		return -1;
	}

	overflow = false;
	int count = 0;
	int validNonces = 0;
	double errorCount = 0;

	applog(LOG_DEBUG, "%s: entering poll loop", ztex->repr);
	while (!(overflow || thr->work_restart)) {
		count++;

		int sleepcount = 0;
		while (thr->work_restart == 0 && sleepcount < 25) {
			nmsleep(10);
			sleepcount += 1;
		}

		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}

		ztex_selectFpga(ztex);
		i = libztex_readHashData(ztex, &hdata[0]);
		if (i < 0) {
			// Something wrong happened in read
			applog(LOG_ERR, "%s: Failed to read hash data with err %d, retrying", ztex->repr, i);
			nmsleep(500);
			i = libztex_readHashData(ztex, &hdata[0]);
			if (i < 0) {
				// And there's nothing we can do about it
				ztex_disable(thr);
				applog(LOG_ERR, "%s: Failed to read hash data with err %d, giving up", ztex->repr, i);
				free(lastnonce);
				free(backlog);
				ztex_releaseFpga(ztex);
				return -1;
			}
		}
		ztex_releaseFpga(ztex);

		if (thr->work_restart) {
			applog(LOG_DEBUG, "%s: New work detected", ztex->repr);
			break;
		}

		ztex->errorCount[ztex->freqM] *= 0.995;
		ztex->errorWeight[ztex->freqM] = ztex->errorWeight[ztex->freqM] * 0.995 + 1.0;

		for (i = 0; i < ztex->numNonces; i++) {
			nonce = hdata[i].nonce;
			//if (nonce > noncecnt)  by smartbitcoin
			// fix the verilog bug which send  INT_MAX as nonce sometime.
			// NB:  cgminer , nonce counter was int64, but ztex driver was int32.
			if( nonce > noncecnt && nonce <  1<<28 )
				noncecnt = nonce;
			// KRAMBLE don't overflow if nonce == 0 (eg if fpga is not hashing)
			if ( (((0xffffffff - nonce) < (nonce - lastnonce[i])) || nonce < lastnonce[i]) && nonce ) {
				applog(LOG_INFO, "%s: overflow nonce=%08x lastnonce=%08x", ztex->repr, nonce, lastnonce[i]);	// KRAMBLE not in production ??
				// applog(LOG_DEBUG, "%s: overflow nonce=%08x lastnonce=%08x", ztex->repr, nonce, lastnonce[i]);
				// overflow = true;		// KRAMBLE disabled as it should not happen at litecoin hash rates (except when broken
										// so leave warning message enabled)
			} else
				lastnonce[i] = nonce;
				
			// KRAMBLE try forcing overflow every so often to see if this fixes DIFF & SICK problems
			// if (nonce > 0x00040000)	// Overflow every 256k nonces (a few times a minute, depending on hash rate)
			if (nonce > 0x00100000)	// Overflow every 1M nonces (single core needs larger range to avoid duplicates)
			{
				// applog(LOG_INFO, "%s: force overflow nonce=%08x lastnonce=%08x", ztex->repr, nonce, lastnonce[i]);	// KRAMBLE not in production
 				overflow = true;
			}

			if (ztex_checkNonce(work, nonce) != (hdata->hash7)) {
				applog(LOG_INFO, "%s: checkNonce failed for %08X hash7 %08X", ztex->repr, nonce, hdata->hash7);		// KRAMBLE not in production ??
				// applog(LOG_DEBUG, "%s: checkNonce failed for %08X", ztex->repr, nonce);

				// do not count errors in the first 500ms after sendHashData (2x250 wait time)
				if (count > 2) {
				
					thr->cgpu->hw_errors++;
					errorCount += (1.0 / ztex->numNonces);
				}
			}
			else
				validNonces++;

			for (j=0; j<=ztex->extraSolutions; j++) {
				nonce = hdata[i].goldenNonce[j];

				if (nonce == ztex->offsNonces) {
					continue;
				}

				// precheck the extraSolutions since they often fail
				if (j > 0 && ztex_checkNonce(work, nonce) != 0) {
					continue;
				}

				found = false;
				for (k = 0; k < backlog_max; k++) {
					if (backlog[k] == nonce) {
						found = true;
						break;
					}
				}
				if (!found) {
					applog(LOG_INFO, "%s: Share found %08x", ztex->repr, nonce);		// KRAMBLE useful to show its working
					// applog(LOG_DEBUG, "%s: Share found N%dE%d", ztex->repr, i, j);
					backlog[backlog_p++] = nonce;

					if (backlog_p >= backlog_max)
						backlog_p = 0;

					work->blk.nonce = 0xffffffff;
					submit_nonce(thr, work, nonce);
					applog(LOG_DEBUG, "%s: submitted %08x", ztex->repr, nonce);					
				}
			}
		}
	}

	// only add the errorCount if we had at least some valid nonces or
	// had no valid nonces in the last round
	if (errorCount > 0.0) {
		if (ztex->nonceCheckValid > 0 && validNonces == 0) {
			applog(LOG_ERR, "%s: resetting %.1f errors", ztex->repr, errorCount);
		}
		else {
			ztex->errorCount[ztex->freqM] += errorCount;
		}
	}

	// remember the number of valid nonces for the check in the next round
	ztex->nonceCheckValid = validNonces;

	ztex->errorRate[ztex->freqM] = ztex->errorCount[ztex->freqM] /	ztex->errorWeight[ztex->freqM] * (ztex->errorWeight[ztex->freqM] < 100? ztex->errorWeight[ztex->freqM] * 0.01: 1.0);
	if (ztex->errorRate[ztex->freqM] > ztex->maxErrorRate[ztex->freqM])
		ztex->maxErrorRate[ztex->freqM] = ztex->errorRate[ztex->freqM];

	// KRAMBLE Disable ztex_updateFreq if lockClock flag set (ie --ztex-clock set initial and max freq to the same value)
	if (!ztex->lockClock) {
		if (!ztex_updateFreq(ztex)) {
			// Something really serious happened, so mark this thread as dead!
			free(lastnonce);
			free(backlog);
			
			return -1;
		}
	}

	applog(LOG_DEBUG, "%s: exit %1.8X", ztex->repr, noncecnt);

	work->blk.nonce = 0xffffffff;

	free(lastnonce);
	free(backlog);

	return noncecnt;
}