static void epiphany_detect()
{
	e_platform_t platform;

	if (e_init(NULL) == E_ERR)
		return;

	if (e_reset_system() == E_ERR)
		return;

	if (e_get_platform_info(&platform) == E_ERR)
		return;

	struct cgpu_info *epiphany = malloc(sizeof(struct cgpu_info));

	if (unlikely(!epiphany))
		quit(1, "Failed to malloc epiphany");

	epiphany->drv = &epiphany_drv;
	epiphany->deven = DEV_ENABLED;
	epiphany->threads = 1;
	epiphany->epiphany_rows = platform.rows;
	epiphany->epiphany_cols = platform.cols;
	epiphany->kname = "Epiphany Scrypt";
	add_cgpu(epiphany);

}
예제 #2
0
static struct cgpu_info *hfa_detect_one(libusb_device *dev, struct usb_find_devices *found)
{
    struct cgpu_info *hashfast;

    hashfast = usb_alloc_cgpu(&hashfast_drv, HASHFAST_MINER_THREADS);
    if (!hashfast)
        quit(1, "Failed to usb_alloc_cgpu hashfast");

    if (!usb_init(hashfast, dev, found)) {
        hashfast = usb_free_cgpu(hashfast);
        return NULL;
    }

    hashfast->usbdev->usb_type = USB_TYPE_STD;

    if (!hfa_initialise(hashfast)) {
        hashfast = usb_free_cgpu(hashfast);
        return NULL;
    }
    if (opt_hfa_dfu_boot) {
        hfa_dfu_boot(hashfast);
        hashfast = usb_free_cgpu(hashfast);
        return NULL;
    }
    if (!hfa_detect_common(hashfast)) {
        usb_uninit(hashfast);
        hashfast = usb_free_cgpu(hashfast);
        return NULL;
    }
    if (!add_cgpu(hashfast))
        return NULL;

    return hashfast;
}
static int cpu_autodetect()
{
	RUNONCE(0);
	
	int i;

	// Reckon number of cores in the box
	#if defined(WIN32)
	{
		DWORD_PTR system_am;
		DWORD_PTR process_am;
		BOOL ok = GetProcessAffinityMask(
			GetCurrentProcess(),
			&system_am,
			&process_am
		);
		if (!ok) {
			applog(LOG_ERR, "couldn't figure out number of processors :(");
			num_processors = 1;
		} else {
			size_t n = 32;
			num_processors = 0;
			while (n--)
				if (process_am & (1<<n))
					++num_processors;
		}
	}
	#elif defined(_SC_NPROCESSORS_CONF)
		num_processors = sysconf(_SC_NPROCESSORS_CONF);
	#elif defined(CTL_HW) && defined(HW_NCPU)
		int req[] = { CTL_HW, HW_NCPU };
		size_t len = sizeof(num_processors);
		sysctl(req, 2, &num_processors, &len, NULL, 0);
	#else
		num_processors = 1;
	#endif /* !WIN32 */

	if (opt_n_threads < 0 || !forced_n_threads) {
			opt_n_threads = num_processors;
	}
	if (num_processors < 1)
		return 0;

	cpus = calloc(opt_n_threads, sizeof(struct cgpu_info));
	if (unlikely(!cpus))
		quit(1, "Failed to calloc cpus");
	for (i = 0; i < opt_n_threads; ++i) {
		struct cgpu_info *cgpu;

		cgpu = &cpus[i];
		cgpu->drv = &cpu_drv;
		cgpu->deven = DEV_ENABLED;
		cgpu->threads = 1;
#ifdef USE_SHA256D
		cgpu->kname = algo_names[opt_algo];
#endif
		add_cgpu(cgpu);
	}
	return opt_n_threads;
}
static void spondoolies_detect_sp50(__maybe_unused bool hotplug)
{
    struct cgpu_info *cgpu = calloc(1, sizeof(struct cgpu_info));
    struct device_drv *drv = &sp50_drv;
    struct spond_adapter *device;
    int i;
    assert(cgpu);
    cgpu->drv = drv;
    cgpu->deven = DEV_ENABLED;
    cgpu->threads = 1;
    cgpu->device_data = calloc(1, sizeof(struct spond_adapter));
    assert(cgpu->device_data);
    device = cgpu->device_data;
    device->cgpu = (void *)cgpu;
    device->current_job_id = 0;;
    pthread_mutex_init(&device->lock, NULL);
    device->socket_fd = init_socket();
    for (i = 0 ; i < MAX_JOBS_IN_MINERGATE; i++) {
        // clean structure
        memset(&device->my_jobs[i], 0, sizeof(spond_driver_work));
        // init our internal lock
        cglock_init(&(device->my_jobs[i].data_lock));
        // init lock for cgminer needs (make sure we are not broken)
        cglock_init(&(device->my_jobs[i].pool.data_lock));
    }
    if (device->socket_fd < 1) {
        quit(1, "Error connecting to minergate server!");
    }
    assert(add_cgpu(cgpu));
    // setup time
	device->last_stats = time(NULL);
    SPONDLOG(LOG_DEBUG, "done");
}
예제 #5
0
static void opencl_detect()
{
	int i;

	nDevs = clDevicesNum();
	if (nDevs < 0) {
		applog(LOG_ERR, "clDevicesNum returned error, no GPUs usable");
		nDevs = 0;
	}

	if (!nDevs)
		return;

	for (i = 0; i < nDevs; ++i) {
		struct cgpu_info *cgpu;

		cgpu = &gpus[i];
		cgpu->deven = DEV_ENABLED;
		cgpu->api = &opencl_api;
		cgpu->device_id = i;
		cgpu->threads = opt_g_threads;
		cgpu->virtual_gpu = i;
		add_cgpu(cgpu);
	}

	if (!opt_noadl)
		init_adl(nDevs);
}
예제 #6
0
static void ztex_detect(void)
{
	int cnt;
	int i,j;
	int fpgacount;
	struct libztex_dev_list **ztex_devices;
	struct libztex_device *ztex_slave;
	struct cgpu_info *ztex;

	cnt = libztex_scanDevices(&ztex_devices);
	if (cnt > 0)
		applog(LOG_WARNING, "Found %d ztex board%s", cnt, cnt > 1 ? "s" : "");

	for (i = 0; i < cnt; i++) {
		ztex = calloc(1, sizeof(struct cgpu_info));
		ztex->api = &ztex_api;
		ztex->device_ztex = ztex_devices[i]->dev;
		ztex->threads = 1;
		ztex->device_ztex->fpgaNum = 0;
		ztex->device_ztex->root = ztex->device_ztex;
		add_cgpu(ztex);

		fpgacount = libztex_numberOfFpgas(ztex->device_ztex);

		if (fpgacount > 1)
			pthread_mutex_init(&ztex->device_ztex->mutex, NULL);

		for (j = 1; j < fpgacount; j++) {
			ztex = calloc(1, sizeof(struct cgpu_info));
			ztex->api = &ztex_api;
			ztex_slave = calloc(1, sizeof(struct libztex_device));
			memcpy(ztex_slave, ztex_devices[i]->dev, sizeof(struct libztex_device));
			ztex->device_ztex = ztex_slave;
			ztex->threads = 1;
			ztex_slave->fpgaNum = j;
			ztex_slave->root = ztex_devices[i]->dev;
			ztex_slave->repr[strlen(ztex_slave->repr) - 1] = ('1' + j);
			add_cgpu(ztex);
		}

		applog(LOG_WARNING,"%s: Found Ztex (fpga count = %d) , mark as %d", ztex->device_ztex->repr, fpgacount, ztex->device_id);
	}

	if (cnt > 0)
		libztex_freeDevList(ztex_devices);
}
예제 #7
0
static void cpu_detect()
{
	int i;

	// Reckon number of cores in the box
	#if defined(WIN32)
	{
		DWORD system_am;
		DWORD process_am;
		BOOL ok = GetProcessAffinityMask(
			GetCurrentProcess(),
			&system_am,
			&process_am
		);
		if (!ok) {
			applog(LOG_ERR, "couldn't figure out number of processors :(");
			num_processors = 1;
		} else {
			size_t n = 32;
			num_processors = 0;
			while (n--)
				if (process_am & (1<<n))
					++num_processors;
		}
	}
	#else
		num_processors = sysconf(_SC_NPROCESSORS_ONLN);
	#endif /* !WIN32 */

	if (opt_n_threads < 0 || !forced_n_threads) {
		if (total_devices && !opt_usecpu)
			opt_n_threads = 0;
		else
			opt_n_threads = num_processors;
	}
	if (num_processors < 1)
		return;

	if (total_devices + opt_n_threads > MAX_DEVICES)
		opt_n_threads = MAX_DEVICES - total_devices;
	cpus = calloc(opt_n_threads, sizeof(struct cgpu_info));
	if (unlikely(!cpus))
		quit(1, "Failed to calloc cpus");
	for (i = 0; i < opt_n_threads; ++i) {
		struct cgpu_info *cgpu;

		cgpu = &cpus[i];
		cgpu->api = &cpu_api;
		cgpu->deven = DEV_ENABLED;
		cgpu->threads = 1;
		cgpu->kname = algo_names[opt_algo];
		add_cgpu(cgpu);
	}
}
예제 #8
0
static bool bitforce_detect_one(const char *devpath)
{
	int fdDev = BFopen(devpath);
	struct cgpu_info *bitforce;
	char pdevbuf[0x100];
	char *s;

	applog(LOG_DEBUG, "BFL: Attempting to open %s", devpath);

	if (unlikely(fdDev == -1)) {
		applog(LOG_ERR, "BFL: Failed to open %s", devpath);
		return false;
	}

	BFwrite(fdDev, "ZGX", 3);
	pdevbuf[0] = '\0';
	BFgets(pdevbuf, sizeof(pdevbuf), fdDev);
	if (unlikely(!pdevbuf[0])) {
		applog(LOG_ERR, "BFL: Error reading/timeout (ZGX)");
		return 0;
	}

	BFclose(fdDev);
	if (unlikely(!strstr(pdevbuf, "SHA256"))) {
		applog(LOG_ERR, "BFL: Didn't recognise BitForce on %s", devpath);
		return false;
	}

	// We have a real BitForce!
	bitforce = calloc(1, sizeof(*bitforce));
	bitforce->api = &bitforce_api;
	bitforce->device_path = strdup(devpath);
	bitforce->deven = DEV_ENABLED;
	bitforce->threads = 1;
	/* 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 (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) {
		s[0] = '\0';
		bitforce->name = strdup(pdevbuf + 7);
	}

	mutex_init(&bitforce->device_mutex);

	return add_cgpu(bitforce);
}
static void opencl_detect(bool hotplug)
{
	int i;

	if (opt_nogpu || hotplug)
		return;
	nDevs = clDevicesNum();
	if (nDevs < 0) {
		applog(LOG_ERR, "clDevicesNum returned error, no GPUs usable");
		nDevs = 0;
	}

	if (!nDevs)
		return;

	/* If opt_g_threads is not set, use default 1 thread on scrypt and
	 * 2 for regular mining */
	if (opt_g_threads == -1) {
		if (opt_scrypt)
			opt_g_threads = 1;
		else
			opt_g_threads = 2;
	}

	if (opt_scrypt)
		opencl_drv.max_diff = 65536;

	for (i = 0; i < nDevs; ++i) {
		struct cgpu_info *cgpu;

		cgpu = &gpus[i];
		cgpu->deven = DEV_ENABLED;
		cgpu->drv = &opencl_drv;
		cgpu->device_id = i;
#ifndef HAVE_ADL
		cgpu->threads = opt_g_threads;
#else
		if (cgpu->threads < 1)
			cgpu->threads = 1;
#endif
		cgpu->virtual_gpu = i;
		add_cgpu(cgpu);
	}

	if (!opt_noadl)
		init_adl(nDevs);
}
static bool serial_fpga_detect_one(const char *devpath)
{
	struct FPGA_INFO *info;
	struct cgpu_info *serial_fpga;
	int fd;

	applog(LOG_DEBUG, "serial_fpga_detect_one...");
	
	fd = serial_open(devpath, SERIAL_IO_SPEED, SERIAL_READ_TIMEOUT, true);
	if (fd == -1) {
		applog(LOG_ERR, "Serial FPGA Detect: Failed to open %s", devpath);
		return false;
	}

//
	applog(LOG_DEBUG, "Serial FPGA Detect: Test skipped for: %s", devpath);
	close(fd);
//

	serial_fpga = calloc(1, sizeof(struct cgpu_info));
	if (unlikely(!serial_fpga))
		quit(1, "Failed to calloc cgpu for %s in usb_alloc_cgpu", devpath);
	serial_fpga->drv = &serial_fpga_drv;
	serial_fpga->device_path = strdup(devpath);
	serial_fpga->threads = 1;
	add_cgpu(serial_fpga);
	
	info = (struct FPGA_INFO *)calloc(1, sizeof(struct FPGA_INFO));
	if (unlikely(!info))
		quit(1, "Failed to malloc FPGA_INFO");
	serial_fpga->device_data = (void *)info;
	
	applog(LOG_INFO, "Found Serial FPGA at %s, mark as %d",	devpath, serial_fpga->device_id);

	// Initialise everything to zero for a new device
	memset(info, 0, sizeof(struct FPGA_INFO));

	info->device_fd = -1;
	info->Hs = DEFAULT_HASH_PER_SEC;
	
	if (opt_scantime > 0)
		info->timeout = opt_scantime;
	else
		info->timeout = SERIAL_FPGA_TIMEOUT;
	
	return true;
}
static struct cgpu_info *ztex_setup(struct libztex_device *dev, int fpgacount)
{
	struct cgpu_info *ztex;
	char *fpganame = (char*)dev->snString;

	ztex = calloc(1, sizeof(struct cgpu_info));
	ztex->drv = &ztex_drv;
	ztex->device_ztex = dev;
	ztex->procs = fpgacount;
	ztex->threads = fpgacount;
	ztex->dev_manufacturer = dev->dev_manufacturer;
	ztex->dev_product = dev->dev_product;
	ztex->dev_serial = (char*)&dev->snString[0];
	ztex->name = fpganame;
	add_cgpu(ztex);
	strcpy(ztex->device_ztex->repr, ztex->dev_repr);
	applog(LOG_INFO, "%"PRIpreprv": Found Ztex (ZTEX %s)", ztex->dev_repr, fpganame);

	return ztex;
}
예제 #12
0
static void opencl_detect(void)
{
  int i;

  nDevs = clDevicesNum();
  if (nDevs < 0) {
    applog(LOG_ERR, "clDevicesNum returned error, no GPUs usable");
    nDevs = 0;
  }

  if (!nDevs)
    return;

  /* If opt_g_threads is not set, use default 1 thread */
  if (opt_g_threads == -1)
    opt_g_threads = 1;

  opencl_drv.max_diff = 65536;

  for (i = 0; i < nDevs; ++i) {
    struct cgpu_info *cgpu;

    cgpu = &gpus[i];
    cgpu->deven = DEV_ENABLED;
    cgpu->drv = &opencl_drv;
    cgpu->thr = NULL;
    cgpu->device_id = i;
#ifndef HAVE_ADL
    cgpu->threads = opt_g_threads;
#else
    if (cgpu->threads < 1)
      cgpu->threads = 1;
#endif
    cgpu->virtual_gpu = i;
    cgpu->algorithm = default_profile.algorithm;
    add_cgpu(cgpu);
  }

  if (!opt_noadl)
    init_adl(nDevs);
}
예제 #13
0
static void bitfury_detect(void)
{
	int chip_n;
	int i;
	struct cgpu_info *bitfury_info;

	bitfury_info = calloc(1, sizeof(struct cgpu_info));
	bitfury_info->drv = &bitfury_drv;
	bitfury_info->threads = 1;

	applog(LOG_INFO, "INFO: bitfury_detect");
	chip_n = libbitfury_detectChips(bitfury_info->devices);
	if (!chip_n) {
		applog(LOG_WARNING, "No Bitfury chips detected!");
		return;
	} else {
		applog(LOG_WARNING, "BITFURY: %d chips detected!", chip_n);
	}

	bitfury_info->chip_n = chip_n;
	add_cgpu(bitfury_info);
}
예제 #14
0
static void spondoolies_detect_sp30(__maybe_unused bool hotplug)
{
	struct cgpu_info *cgpu = calloc(1, sizeof(*cgpu));
	struct device_drv *drv = &sp30_drv;
	struct spond_adapter *a;

#if NEED_FIX
	nDevs = 1;
#endif

	assert(cgpu);
	cgpu->drv = drv;
	cgpu->deven = DEV_ENABLED;
	cgpu->threads = 1;
	cgpu->device_data = calloc(sizeof(struct spond_adapter), 1);
	if (unlikely(!(cgpu->device_data)))
		quit(1, "Failed to calloc cgpu_info data");
	a = cgpu->device_data;
	a->cgpu = (void *)cgpu;
	a->adapter_state = ADAPTER_STATE_OPERATIONAL;
	a->mp_next_req = allocate_minergate_packet_req_sp30(0xca, 0xfe);
	a->mp_last_rsp = allocate_minergate_packet_rsp_sp30(0xca, 0xfe);

	pthread_mutex_init(&a->lock, NULL);
	a->socket_fd = init_socket();
	if (a->socket_fd < 1) {
		applog(LOG_ERR, "SP30: Failed to connect to minergate server");
		_quit(-1);
	}

	assert(add_cgpu(cgpu));
	// Clean MG socket
	spondoolies_flush_queue(a, true);
	spondoolies_flush_queue(a, true);
	spondoolies_flush_queue(a, true);
	applog(LOG_DEBUG, "SP30: SPOND spondoolies_detect_sp30 done");
}
예제 #15
0
static bool hfa_detect_one_usb(libusb_device *dev, struct usb_find_devices *found)
{
	struct cgpu_info *hashfast;

	hashfast = usb_alloc_cgpu(&hashfast_drv, HASHFAST_MINER_THREADS);
	if (!hashfast)
		quit(1, "Failed to usb_alloc_cgpu hashfast");

	if (!usb_init(hashfast, dev, found)) {
		hashfast = usb_free_cgpu(hashfast);
		return false;
	}

	hashfast->usbdev->usb_type = USB_TYPE_STD;

	if (!hfa_initialise(hashfast)) {
		hashfast = usb_free_cgpu(hashfast);
		return false;
	}

	add_cgpu(hashfast);

	return hfa_detect_common(hashfast);
}
예제 #16
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;
}
예제 #17
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;
}
예제 #18
0
void add_cgpu_live(void *p)
{
	add_cgpu(p);
}
예제 #19
0
static bool avalon2_detect_one(const char *devpath)
{
	struct avalon2_info *info;
	int ackdetect;
	int fd;
	int tmp, i, j, modular[AVA2_DEFAULT_MODULARS];
	char mm_version[AVA2_DEFAULT_MODULARS][16];

	struct cgpu_info *avalon2;
	struct avalon2_pkg detect_pkg;
	struct avalon2_ret ret_pkg;

	applog(LOG_DEBUG, "Avalon2 Detect: Attempting to open %s", devpath);

	fd = avalon2_open(devpath, AVA2_IO_SPEED, true);
	if (unlikely(fd == -1)) {
		applog(LOG_ERR, "Avalon2 Detect: Failed to open %s", devpath);
		return false;
	}
	tcflush(fd, TCIOFLUSH);

	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++)
		modular[i] = 0;

	for (j = 0; j < 2; j++) {
		for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
			strcpy(mm_version[i], AVA2_MM_VERNULL);
			/* Send out detect pkg */
			memset(detect_pkg.data, 0, AVA2_P_DATA_LEN);
			tmp = be32toh(i);
			memcpy(detect_pkg.data + 28, &tmp, 4);

			avalon2_init_pkg(&detect_pkg, AVA2_P_DETECT, 1, 1);
			avalon2_send_pkg(fd, &detect_pkg, NULL);
			ackdetect = avalon2_get_result(NULL, fd, &ret_pkg);
			applog(LOG_DEBUG, "Avalon2 Detect ID[%d]: %d", i, ackdetect);
			if (ackdetect != AVA2_P_ACKDETECT && modular[i] == 0)
				continue;
			modular[i] = 1;
			memcpy(mm_version[i], ret_pkg.data, 15);
			mm_version[i][15] = '\0';
		}
	}
	avalon2_close(fd);
	if (!modular[0] && !modular[1] && !modular[2] && !modular[3])
		return false;

	/* We have a real Avalon! */
	avalon2 = calloc(1, sizeof(struct cgpu_info));
	avalon2->drv = &avalon2_drv;
	avalon2->device_path = strdup(devpath);
	avalon2->threads = AVA2_MINER_THREADS;
	add_cgpu(avalon2);

	applog(LOG_INFO, "Avalon2 Detect: Found at %s, mark as %d",
	       devpath, avalon2->device_id);

	avalon2->device_data = calloc(sizeof(struct avalon2_info), 1);
	if (unlikely(!(avalon2->device_data)))
		quit(1, "Failed to malloc avalon2_info");

	info = avalon2->device_data;

	info->fd = -1;
	info->baud = AVA2_IO_SPEED;
	info->fan_pwm = AVA2_DEFAULT_FAN_PWM;
	info->set_voltage = AVA2_DEFAULT_VOLTAGE_MIN;
	info->set_frequency = AVA2_DEFAULT_FREQUENCY;
	info->temp_max = 0;

	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
		strcpy(info->mm_version[i], mm_version[i]);
		info->modulars[i] = modular[i];	/* Enable modular */
		info->enable[i] = modular[i];
		info->dev_type[i] = AVA2_ID_AVAX;

		if (!strncmp((char *)&(info->mm_version[i]), AVA2_FW2_PREFIXSTR, 2))
			info->dev_type[i] = AVA2_ID_AVA2;
		if (!strncmp((char *)&(info->mm_version[i]), AVA2_FW3_PREFIXSTR, 2))
			info->dev_type[i] = AVA2_ID_AVA3;
	}

	pool_stratum.swork.job_id = NULL;
	pool_stratum.merkles = 0;
	return true;
}
예제 #20
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;
}
예제 #21
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;
}
예제 #22
0
static bool avalon2_detect_one(const char *devpath)
{
	struct avalon2_info *info;
	int ackdetect;
	int fd;
	int tmp, i, modular[3];
	char mm_version[AVA2_DEFAULT_MODULARS][16];

	struct cgpu_info *avalon2;
	struct avalon2_pkg detect_pkg;
	struct avalon2_ret ret_pkg;

	applog(LOG_DEBUG, "Avalon2 Detect: Attempting to open %s", devpath);

	fd = avalon2_open(devpath, AVA2_IO_SPEED, true);
	if (unlikely(fd == -1)) {
		applog(LOG_ERR, "Avalon2 Detect: Failed to open %s", devpath);
		return false;
	}
	tcflush(fd, TCIOFLUSH);

	for (i = 0; i < AVA2_DEFAULT_MODULARS; i++) {
		modular[i] = 0;
		strcpy(mm_version[i], "NONE");
		/* Send out detect pkg */
		memset(detect_pkg.data, 0, AVA2_P_DATA_LEN);
		tmp = be32toh(i);
		memcpy(detect_pkg.data + 28, &tmp, 4);

		avalon2_init_pkg(&detect_pkg, AVA2_P_DETECT, 1, 1);
		avalon2_send_pkg(fd, &detect_pkg, NULL);
		ackdetect = avalon2_get_result(NULL, fd, &ret_pkg);
		applog(LOG_DEBUG, "Avalon2 Detect ID[%d]: %d", i, ackdetect);
		if (ackdetect != AVA2_P_ACKDETECT)
			continue;
		modular[i] = 1;
		memcpy(mm_version[i], ret_pkg.data, 15);
		mm_version[i][15] = '\0';
	}
	if (!modular[0] && !modular[1] && !modular[2])
		return false;

	/* We have a real Avalon! */
	avalon2 = calloc(1, sizeof(struct cgpu_info));
	avalon2->drv = &avalon2_drv;
	avalon2->device_path = strdup(devpath);
	avalon2->threads = AVA2_MINER_THREADS;
	add_cgpu(avalon2);

	applog(LOG_INFO, "Avalon2 Detect: Found at %s, mark as %d",
	       devpath, avalon2->device_id);

	avalon2->device_data = calloc(sizeof(struct avalon2_info), 1);
	if (unlikely(!(avalon2->device_data)))
		quit(1, "Failed to malloc avalon2_info");

	info = avalon2->device_data;

	strcpy(info->mm_version[0], mm_version[0]);
	strcpy(info->mm_version[1], mm_version[1]);
	strcpy(info->mm_version[2], mm_version[2]);

	info->baud = AVA2_IO_SPEED;
	info->fan_pwm = AVA2_DEFAULT_FAN_PWM;
	info->set_voltage = AVA2_DEFAULT_VOLTAGE_MIN;
	info->set_frequency = AVA2_DEFAULT_FREQUENCY;
	info->temp_max = 0;
	info->temp_history_index = 0;
	info->temp_sum = 0;
	info->temp_old = 0;
	info->modulars[0] = modular[0];
	info->modulars[1] = modular[1];
	info->modulars[2] = modular[2];	/* Enable modular */

	info->fd = -1;
	/* Set asic to idle mode after detect */
	avalon2_close(fd);

	return true;
}
예제 #23
0
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;
}
예제 #24
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;
}
예제 #25
0
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;
}