mirror of
https://github.com/GOSTSec/sgminer
synced 2025-02-02 01:44:23 +00:00
Abstract generally useful FPGA code into fpgautils.c
This commit is contained in:
parent
07549b0d04
commit
d3fa59d76f
@ -68,6 +68,10 @@ endif # HAVE_x86_64
|
|||||||
endif # HAS_YASM
|
endif # HAS_YASM
|
||||||
endif # HAS_CPUMINE
|
endif # HAS_CPUMINE
|
||||||
|
|
||||||
|
if NEED_FPGAUTILS
|
||||||
|
cgminer_SOURCES += fpgautils.c
|
||||||
|
endif
|
||||||
|
|
||||||
if HAS_BITFORCE
|
if HAS_BITFORCE
|
||||||
cgminer_SOURCES += driver-bitforce.c
|
cgminer_SOURCES += driver-bitforce.c
|
||||||
endif
|
endif
|
||||||
|
2
README
2
README
@ -129,6 +129,7 @@ Options for both config file and command line:
|
|||||||
--debug|-D Enable debug output
|
--debug|-D Enable debug output
|
||||||
--expiry|-E <arg> Upper bound on how many seconds after getting work we consider a share from it stale (default: 120)
|
--expiry|-E <arg> Upper bound on how many seconds after getting work we consider a share from it stale (default: 120)
|
||||||
--failover-only Don't leak work to backup pools when primary pool is lagging
|
--failover-only Don't leak work to backup pools when primary pool is lagging
|
||||||
|
--kernel-path|-K <arg> Specify a path to where bitstream and kernel files are (default: "/usr/local/bin")
|
||||||
--load-balance Change multipool strategy from failover to even load balance
|
--load-balance Change multipool strategy from failover to even load balance
|
||||||
--log|-l <arg> Interval in seconds between log output (default: 5)
|
--log|-l <arg> Interval in seconds between log output (default: 5)
|
||||||
--monitor|-m <arg> Use custom pipe cmd for output messages
|
--monitor|-m <arg> Use custom pipe cmd for output messages
|
||||||
@ -184,7 +185,6 @@ GPU only options:
|
|||||||
--gpu-vddc <arg> Set the GPU voltage in Volts - one value for all or separate by commas for per card.
|
--gpu-vddc <arg> Set the GPU voltage in Volts - one value for all or separate by commas for per card.
|
||||||
--intensity|-I <arg> Intensity of GPU scanning (d or -10 -> 10, default: d to maintain desktop interactivity)
|
--intensity|-I <arg> Intensity of GPU scanning (d or -10 -> 10, default: d to maintain desktop interactivity)
|
||||||
--kernel|-k <arg> Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated
|
--kernel|-k <arg> Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated
|
||||||
--kernel-path|-K <arg> Specify a path to where the kernel .cl files are (default: "/usr/local/bin")
|
|
||||||
--ndevs|-n Enumerate number of detected GPUs and exit
|
--ndevs|-n Enumerate number of detected GPUs and exit
|
||||||
--no-restart Do not attempt to restart GPUs that hang
|
--no-restart Do not attempt to restart GPUs that hang
|
||||||
--temp-hysteresis <arg> Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3)
|
--temp-hysteresis <arg> Set how much the temperature can fluctuate outside limits when automanaging speeds (default: 3)
|
||||||
|
31
cgminer.c
31
cgminer.c
@ -54,6 +54,13 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_MODMINER)
|
||||||
|
# define USE_FPGA
|
||||||
|
# define USE_FPGA_SERIAL
|
||||||
|
#elif defined(USE_ZTEX)
|
||||||
|
# define USE_FPGA
|
||||||
|
#endif
|
||||||
|
|
||||||
enum workio_commands {
|
enum workio_commands {
|
||||||
WC_GET_WORK,
|
WC_GET_WORK,
|
||||||
WC_SUBMIT_WORK,
|
WC_SUBMIT_WORK,
|
||||||
@ -468,7 +475,7 @@ static char *set_int_1_to_10(const char *arg, int *i)
|
|||||||
return set_int_range(arg, i, 1, 10);
|
return set_int_range(arg, i, 1, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_BITFORCE) || defined(USE_ICARUS)
|
#ifdef USE_FPGA_SERIAL
|
||||||
static char *add_serial(char *arg)
|
static char *add_serial(char *arg)
|
||||||
{
|
{
|
||||||
string_elist_add(arg, &scan_devices);
|
string_elist_add(arg, &scan_devices);
|
||||||
@ -768,7 +775,7 @@ static struct opt_table opt_config_table[] = {
|
|||||||
opt_hidden
|
opt_hidden
|
||||||
#endif
|
#endif
|
||||||
),
|
),
|
||||||
#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(USE_BITFORCE) || defined(USE_ICARUS))
|
#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(USE_FPGA))
|
||||||
OPT_WITHOUT_ARG("--enable-cpu|-C",
|
OPT_WITHOUT_ARG("--enable-cpu|-C",
|
||||||
opt_set_bool, &opt_usecpu,
|
opt_set_bool, &opt_usecpu,
|
||||||
"Enable CPU mining with other mining (default: no CPU mining if other devices exist)"),
|
"Enable CPU mining with other mining (default: no CPU mining if other devices exist)"),
|
||||||
@ -818,9 +825,13 @@ static struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITH_ARG("--intensity|-I",
|
OPT_WITH_ARG("--intensity|-I",
|
||||||
set_intensity, NULL, NULL,
|
set_intensity, NULL, NULL,
|
||||||
"Intensity of GPU scanning (d or " _MIN_INTENSITY_STR " -> " _MAX_INTENSITY_STR ", default: d to maintain desktop interactivity)"),
|
"Intensity of GPU scanning (d or " _MIN_INTENSITY_STR " -> " _MAX_INTENSITY_STR ", default: d to maintain desktop interactivity)"),
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_OPENCL) || defined(HAVE_MODMINER)
|
||||||
OPT_WITH_ARG("--kernel-path|-K",
|
OPT_WITH_ARG("--kernel-path|-K",
|
||||||
opt_set_charp, opt_show_charp, &opt_kernel_path,
|
opt_set_charp, opt_show_charp, &opt_kernel_path,
|
||||||
"Specify a path to where the kernel .cl files are"),
|
"Specify a path to where bitstream and kernel files are"),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_OPENCL
|
||||||
OPT_WITH_ARG("--kernel|-k",
|
OPT_WITH_ARG("--kernel|-k",
|
||||||
set_kernel, NULL, NULL,
|
set_kernel, NULL, NULL,
|
||||||
"Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated"),
|
"Override kernel to use (diablo, poclbm, phatk or diakgcn) - one value or comma separated"),
|
||||||
@ -899,7 +910,7 @@ static struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITHOUT_ARG("--round-robin",
|
OPT_WITHOUT_ARG("--round-robin",
|
||||||
set_rr, &pool_strategy,
|
set_rr, &pool_strategy,
|
||||||
"Change multipool strategy from failover to round robin on failure"),
|
"Change multipool strategy from failover to round robin on failure"),
|
||||||
#if defined(USE_BITFORCE) || defined(USE_ICARUS)
|
#ifdef USE_FPGA_SERIAL
|
||||||
OPT_WITH_ARG("--scan-serial|-S",
|
OPT_WITH_ARG("--scan-serial|-S",
|
||||||
add_serial, NULL, NULL,
|
add_serial, NULL, NULL,
|
||||||
"Serial port to probe for FPGA Mining device"),
|
"Serial port to probe for FPGA Mining device"),
|
||||||
@ -927,7 +938,7 @@ static struct opt_table opt_config_table[] = {
|
|||||||
opt_set_bool, &use_syslog,
|
opt_set_bool, &use_syslog,
|
||||||
"Use system log for output messages (default: standard error)"),
|
"Use system log for output messages (default: standard error)"),
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_ADL) || defined(USE_BITFORCE)
|
#if defined(HAVE_ADL) || defined(USE_BITFORCE) || defined(USE_MODMINER)
|
||||||
OPT_WITH_ARG("--temp-cutoff",
|
OPT_WITH_ARG("--temp-cutoff",
|
||||||
set_temp_cutoff, opt_show_intval, &opt_cutofftemp,
|
set_temp_cutoff, opt_show_intval, &opt_cutofftemp,
|
||||||
"Temperature where a device will be automatically disabled, one value or comma separated list"),
|
"Temperature where a device will be automatically disabled, one value or comma separated list"),
|
||||||
@ -3729,15 +3740,21 @@ bool hashtest(const struct work *work)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
bool test_nonce(struct work *work, uint32_t nonce)
|
||||||
{
|
{
|
||||||
work->data[64 + 12 + 0] = (nonce >> 0) & 0xff;
|
work->data[64 + 12 + 0] = (nonce >> 0) & 0xff;
|
||||||
work->data[64 + 12 + 1] = (nonce >> 8) & 0xff;
|
work->data[64 + 12 + 1] = (nonce >> 8) & 0xff;
|
||||||
work->data[64 + 12 + 2] = (nonce >> 16) & 0xff;
|
work->data[64 + 12 + 2] = (nonce >> 16) & 0xff;
|
||||||
work->data[64 + 12 + 3] = (nonce >> 24) & 0xff;
|
work->data[64 + 12 + 3] = (nonce >> 24) & 0xff;
|
||||||
|
|
||||||
|
return hashtest(work);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
|
||||||
|
{
|
||||||
/* Do one last check before attempting to submit the work */
|
/* Do one last check before attempting to submit the work */
|
||||||
if (!hashtest(work)) {
|
/* Side effect: sets work->data for us */
|
||||||
|
if (!test_nonce(work, nonce)) {
|
||||||
applog(LOG_INFO, "Share below target");
|
applog(LOG_INFO, "Share below target");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -245,6 +245,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
AM_CONDITIONAL([NEED_FPGAUTILS], [test x$icarus$bitforce$ztex != xnonono])
|
||||||
AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes])
|
AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes])
|
||||||
AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue])
|
AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue])
|
||||||
AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue])
|
AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue])
|
||||||
|
@ -13,62 +13,17 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#ifndef O_CLOEXEC
|
|
||||||
#define O_CLOEXEC 0
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <windows.h>
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBUDEV
|
#include "fpgautils.h"
|
||||||
#include <libudev.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "elist.h"
|
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
|
||||||
|
|
||||||
struct device_api bitforce_api;
|
struct device_api bitforce_api;
|
||||||
|
|
||||||
static int BFopen(const char *devpath)
|
#define BFopen(devpath) serial_open(devpath, 0, -1, true)
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (unlikely(hSerial == INVALID_HANDLE_VALUE))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
COMMTIMEOUTS cto = {30000, 0, 30000, 0, 30000};
|
|
||||||
SetCommTimeouts(hSerial, &cto);
|
|
||||||
|
|
||||||
return _open_osfhandle((LONG)hSerial, 0);
|
|
||||||
#else
|
|
||||||
int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);
|
|
||||||
if (likely(fdDev != -1)) {
|
|
||||||
struct termios pattr;
|
|
||||||
|
|
||||||
tcgetattr(fdDev, &pattr);
|
|
||||||
pattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
|
||||||
pattr.c_oflag &= ~OPOST;
|
|
||||||
pattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
|
||||||
pattr.c_cflag &= ~(CSIZE | PARENB);
|
|
||||||
pattr.c_cflag |= CS8;
|
|
||||||
tcsetattr(fdDev, TCSANOW, &pattr);
|
|
||||||
}
|
|
||||||
tcflush(fdDev, TCOFLUSH);
|
|
||||||
tcflush(fdDev, TCIFLUSH);
|
|
||||||
return fdDev;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void BFgets(char *buf, size_t bufLen, int fd)
|
static void BFgets(char *buf, size_t bufLen, int fd)
|
||||||
{
|
{
|
||||||
@ -98,9 +53,6 @@ static bool bitforce_detect_one(const char *devpath)
|
|||||||
char *s;
|
char *s;
|
||||||
char pdevbuf[0x100];
|
char pdevbuf[0x100];
|
||||||
|
|
||||||
if (total_devices == MAX_DEVICES)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int fdDev = BFopen(devpath);
|
int fdDev = BFopen(devpath);
|
||||||
if (unlikely(fdDev == -1)) {
|
if (unlikely(fdDev == -1)) {
|
||||||
applog(LOG_DEBUG, "BitForce Detect: Failed to open %s", devpath);
|
applog(LOG_DEBUG, "BitForce Detect: Failed to open %s", devpath);
|
||||||
@ -134,103 +86,17 @@ static bool bitforce_detect_one(const char *devpath)
|
|||||||
return add_cgpu(bitforce);
|
return add_cgpu(bitforce);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bitforce_detect_auto_udev()
|
static char bitforce_detect_auto()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_LIBUDEV
|
return
|
||||||
struct udev *udev = udev_new();
|
serial_autodetect_udev (bitforce_detect_one, "BitFORCE*SHA256") ?:
|
||||||
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
|
serial_autodetect_devserial(bitforce_detect_one, "BitFORCE_SHA256") ?:
|
||||||
struct udev_list_entry *list_entry;
|
|
||||||
bool foundany = false;
|
|
||||||
|
|
||||||
udev_enumerate_add_match_subsystem(enumerate, "tty");
|
|
||||||
udev_enumerate_add_match_property(enumerate, "ID_MODEL", "BitFORCE*SHA256");
|
|
||||||
udev_enumerate_scan_devices(enumerate);
|
|
||||||
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
|
|
||||||
struct udev_device *device = udev_device_new_from_syspath(
|
|
||||||
udev_enumerate_get_udev(enumerate),
|
|
||||||
udev_list_entry_get_name(list_entry)
|
|
||||||
);
|
|
||||||
if (!device)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const char *devpath = udev_device_get_devnode(device);
|
|
||||||
if (devpath) {
|
|
||||||
foundany = true;
|
|
||||||
bitforce_detect_one(devpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
udev_device_unref(device);
|
|
||||||
}
|
|
||||||
udev_enumerate_unref(enumerate);
|
|
||||||
udev_unref(udev);
|
|
||||||
|
|
||||||
return foundany;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool bitforce_detect_auto_devserial()
|
|
||||||
{
|
|
||||||
#ifndef WIN32
|
|
||||||
DIR *D;
|
|
||||||
struct dirent *de;
|
|
||||||
const char udevdir[] = "/dev/serial/by-id";
|
|
||||||
char devpath[sizeof(udevdir) + 1 + NAME_MAX];
|
|
||||||
char *devfile = devpath + sizeof(udevdir);
|
|
||||||
bool foundany = false;
|
|
||||||
|
|
||||||
D = opendir(udevdir);
|
|
||||||
if (!D)
|
|
||||||
return false;
|
|
||||||
memcpy(devpath, udevdir, sizeof(udevdir) - 1);
|
|
||||||
devpath[sizeof(udevdir) - 1] = '/';
|
|
||||||
while ( (de = readdir(D)) ) {
|
|
||||||
if (!strstr(de->d_name, "BitFORCE_SHA256"))
|
|
||||||
continue;
|
|
||||||
foundany = true;
|
|
||||||
strcpy(devfile, de->d_name);
|
|
||||||
bitforce_detect_one(devpath);
|
|
||||||
}
|
|
||||||
closedir(D);
|
|
||||||
|
|
||||||
return foundany;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bitforce_detect_auto()
|
|
||||||
{
|
|
||||||
bitforce_detect_auto_udev() ?:
|
|
||||||
bitforce_detect_auto_devserial() ?:
|
|
||||||
0;
|
0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bitforce_detect()
|
static void bitforce_detect()
|
||||||
{
|
{
|
||||||
struct string_elist *iter, *tmp;
|
serial_detect_auto("bitforce", bitforce_detect_one, bitforce_detect_auto);
|
||||||
const char*s;
|
|
||||||
bool found = false;
|
|
||||||
bool autoscan = false;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(iter, tmp, &scan_devices, list) {
|
|
||||||
s = iter->string;
|
|
||||||
if (!strncmp("bitforce:", iter->string, 9))
|
|
||||||
s += 9;
|
|
||||||
if (!strcmp(s, "auto"))
|
|
||||||
autoscan = true;
|
|
||||||
else
|
|
||||||
if (!strcmp(s, "noauto"))
|
|
||||||
found = true;
|
|
||||||
else if (bitforce_detect_one(s)) {
|
|
||||||
string_elist_del(iter);
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (autoscan || !found)
|
|
||||||
bitforce_detect_auto();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce)
|
static void get_bitforce_statline_before(char *buf, struct cgpu_info *bitforce)
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "elist.h"
|
#include "elist.h"
|
||||||
|
#include "fpgautils.h"
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
|
|
||||||
// The serial I/O speed - Linux uses a define 'B115200' in bits/termios.h
|
// The serial I/O speed - Linux uses a define 'B115200' in bits/termios.h
|
||||||
@ -69,10 +70,8 @@ ASSERT1(sizeof(uint32_t) == 4);
|
|||||||
// Fraction of a second, USB timeout is measured in
|
// Fraction of a second, USB timeout is measured in
|
||||||
// i.e. 10 means 1/10 of a second
|
// i.e. 10 means 1/10 of a second
|
||||||
#define TIME_FACTOR 10
|
#define TIME_FACTOR 10
|
||||||
// In Linux it's 10 per second, thus value = 10/TIME_FACTOR =
|
// It's 10 per second, thus value = 10/TIME_FACTOR =
|
||||||
#define LINUX_TIMEOUT_VALUE 1
|
#define ICARUS_READ_FAULT_DECISECONDS 1
|
||||||
// In Windows it's 1000 per second, thus value = 1000/TIME_FACTOR =
|
|
||||||
#define WINDOWS_TIMEOUT_VALUE 100
|
|
||||||
|
|
||||||
// In timing mode: Default starting value until an estimate can be obtained
|
// In timing mode: Default starting value until an estimate can be obtained
|
||||||
// 5 seconds allows for up to a ~840MH/s device
|
// 5 seconds allows for up to a ~840MH/s device
|
||||||
@ -196,63 +195,8 @@ static void rev(unsigned char *s, size_t l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int icarus_open(const char *devpath)
|
#define icarus_open2(devpath, purge) serial_open(devpath, 115200, ICARUS_READ_FAULT_DECISECONDS, purge)
|
||||||
{
|
#define icarus_open(devpath) icarus_open2(devpath, false)
|
||||||
#ifndef WIN32
|
|
||||||
struct termios my_termios;
|
|
||||||
|
|
||||||
int serialfd = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);
|
|
||||||
|
|
||||||
if (serialfd == -1)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
tcgetattr(serialfd, &my_termios);
|
|
||||||
my_termios.c_cflag = B115200;
|
|
||||||
my_termios.c_cflag |= CS8;
|
|
||||||
my_termios.c_cflag |= CREAD;
|
|
||||||
my_termios.c_cflag |= CLOCAL;
|
|
||||||
my_termios.c_cflag &= ~(CSIZE | PARENB);
|
|
||||||
|
|
||||||
my_termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK |
|
|
||||||
ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
|
||||||
my_termios.c_oflag &= ~OPOST;
|
|
||||||
my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
|
||||||
my_termios.c_cc[VTIME] = LINUX_TIMEOUT_VALUE; /* how long to block */
|
|
||||||
my_termios.c_cc[VMIN] = 0;
|
|
||||||
tcsetattr(serialfd, TCSANOW, &my_termios);
|
|
||||||
|
|
||||||
tcflush(serialfd, TCOFLUSH);
|
|
||||||
tcflush(serialfd, TCIFLUSH);
|
|
||||||
|
|
||||||
return serialfd;
|
|
||||||
#else
|
|
||||||
COMMCONFIG comCfg;
|
|
||||||
|
|
||||||
HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0,
|
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (unlikely(hSerial == INVALID_HANDLE_VALUE))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// thanks to af_newbie for pointers about this
|
|
||||||
memset(&comCfg, 0 , sizeof(comCfg));
|
|
||||||
comCfg.dwSize = sizeof(COMMCONFIG);
|
|
||||||
comCfg.wVersion = 1;
|
|
||||||
comCfg.dcb.DCBlength = sizeof(DCB);
|
|
||||||
comCfg.dcb.BaudRate = ICARUS_IO_SPEED;
|
|
||||||
comCfg.dcb.fBinary = 1;
|
|
||||||
comCfg.dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
|
||||||
comCfg.dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
|
||||||
comCfg.dcb.ByteSize = 8;
|
|
||||||
|
|
||||||
SetCommConfig(hSerial, &comCfg, sizeof(comCfg));
|
|
||||||
|
|
||||||
// How long to block
|
|
||||||
COMMTIMEOUTS cto = {WINDOWS_TIMEOUT_VALUE, 0, WINDOWS_TIMEOUT_VALUE, 0, WINDOWS_TIMEOUT_VALUE};
|
|
||||||
SetCommTimeouts(hSerial, &cto);
|
|
||||||
|
|
||||||
return _open_osfhandle((LONG)hSerial, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int icarus_gets(unsigned char *buf, int fd, struct timeval *tv_finish, int thr_id, int read_count)
|
static int icarus_gets(unsigned char *buf, int fd, struct timeval *tv_finish, int thr_id, int read_count)
|
||||||
{
|
{
|
||||||
@ -435,10 +379,7 @@ static bool icarus_detect_one(const char *devpath)
|
|||||||
unsigned char ob_bin[64], nonce_bin[ICARUS_READ_SIZE];
|
unsigned char ob_bin[64], nonce_bin[ICARUS_READ_SIZE];
|
||||||
char *nonce_hex;
|
char *nonce_hex;
|
||||||
|
|
||||||
if (total_devices == MAX_DEVICES)
|
fd = icarus_open2(devpath, true);
|
||||||
return false;
|
|
||||||
|
|
||||||
fd = icarus_open(devpath);
|
|
||||||
if (unlikely(fd == -1)) {
|
if (unlikely(fd == -1)) {
|
||||||
applog(LOG_ERR, "Icarus Detect: Failed to open %s", devpath);
|
applog(LOG_ERR, "Icarus Detect: Failed to open %s", devpath);
|
||||||
return false;
|
return false;
|
||||||
@ -503,18 +444,7 @@ static bool icarus_detect_one(const char *devpath)
|
|||||||
|
|
||||||
static void icarus_detect()
|
static void icarus_detect()
|
||||||
{
|
{
|
||||||
struct string_elist *iter, *tmp;
|
serial_detect("icarus", icarus_detect_one);
|
||||||
const char*s;
|
|
||||||
|
|
||||||
list_for_each_entry_safe(iter, tmp, &scan_devices, list) {
|
|
||||||
s = iter->string;
|
|
||||||
if (!strncmp("icarus:", iter->string, 7))
|
|
||||||
s += 7;
|
|
||||||
if (!strcmp(s, "auto") || !strcmp(s, "noauto"))
|
|
||||||
continue;
|
|
||||||
if (icarus_detect_one(s))
|
|
||||||
string_elist_del(iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool icarus_prepare(struct thr_info *thr)
|
static bool icarus_prepare(struct thr_info *thr)
|
||||||
|
273
fpgautils.c
Normal file
273
fpgautils.c
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Luke Dashjr
|
||||||
|
* Copyright 2012 Andrew Smith
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 3 of the License, or (at your option)
|
||||||
|
* any later version. See COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <termios.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <windows.h>
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBUDEV
|
||||||
|
#include <libudev.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "elist.h"
|
||||||
|
#include "fpgautils.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "miner.h"
|
||||||
|
|
||||||
|
char
|
||||||
|
serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBUDEV
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct udev *udev = udev_new();
|
||||||
|
struct udev_enumerate *enumerate = udev_enumerate_new(udev);
|
||||||
|
struct udev_list_entry *list_entry;
|
||||||
|
char found = 0;
|
||||||
|
|
||||||
|
udev_enumerate_add_match_subsystem(enumerate, "tty");
|
||||||
|
udev_enumerate_add_match_property(enumerate, "ID_MODEL", prodname);
|
||||||
|
udev_enumerate_scan_devices(enumerate);
|
||||||
|
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
|
||||||
|
struct udev_device *device = udev_device_new_from_syspath(
|
||||||
|
udev_enumerate_get_udev(enumerate),
|
||||||
|
udev_list_entry_get_name(list_entry)
|
||||||
|
);
|
||||||
|
if (!device)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const char *devpath = udev_device_get_devnode(device);
|
||||||
|
if (devpath && detectone(devpath))
|
||||||
|
++found;
|
||||||
|
|
||||||
|
udev_device_unref(device);
|
||||||
|
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
udev_enumerate_unref(enumerate);
|
||||||
|
udev_unref(udev);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
serial_autodetect_devserial(detectone_func_t detectone, const char*prodname)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DIR *D;
|
||||||
|
struct dirent *de;
|
||||||
|
const char udevdir[] = "/dev/serial/by-id";
|
||||||
|
char devpath[sizeof(udevdir) + 1 + NAME_MAX];
|
||||||
|
char *devfile = devpath + sizeof(udevdir);
|
||||||
|
char found = 0;
|
||||||
|
|
||||||
|
D = opendir(udevdir);
|
||||||
|
if (!D)
|
||||||
|
return 0;
|
||||||
|
memcpy(devpath, udevdir, sizeof(udevdir) - 1);
|
||||||
|
devpath[sizeof(udevdir) - 1] = '/';
|
||||||
|
while ( (de = readdir(D)) ) {
|
||||||
|
if (!strstr(de->d_name, prodname))
|
||||||
|
continue;
|
||||||
|
strcpy(devfile, de->d_name);
|
||||||
|
if (detectone(devpath)) {
|
||||||
|
++found;
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(D);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
_serial_detect(const char*dnamec, size_t dnamel, detectone_func_t detectone, autoscan_func_t autoscan, bool force_autoscan)
|
||||||
|
{
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct string_elist *iter, *tmp;
|
||||||
|
const char*s;
|
||||||
|
bool inhibitauto = false;
|
||||||
|
bool forceauto = false;
|
||||||
|
char found = 0;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(iter, tmp, &scan_devices, list) {
|
||||||
|
s = iter->string;
|
||||||
|
if (!strncmp(dnamec, iter->string, dnamel))
|
||||||
|
s += dnamel;
|
||||||
|
if (!strcmp(s, "auto"))
|
||||||
|
forceauto = true;
|
||||||
|
else
|
||||||
|
if (!strcmp(s, "noauto"))
|
||||||
|
inhibitauto = true;
|
||||||
|
else
|
||||||
|
if (detectone(s)) {
|
||||||
|
string_elist_del(iter);
|
||||||
|
inhibitauto = true;
|
||||||
|
++found;
|
||||||
|
if (total_devices == MAX_DEVICES)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((forceauto || !inhibitauto) && autoscan && total_devices < MAX_DEVICES)
|
||||||
|
found += autoscan();
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
serial_open(const char*devpath, unsigned long baud, signed short timeout, bool purge)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
HANDLE hSerial = CreateFile(devpath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||||
|
if (unlikely(hSerial == INVALID_HANDLE_VALUE))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// thanks to af_newbie for pointers about this
|
||||||
|
COMMCONFIG comCfg = {0};
|
||||||
|
comCfg.dwSize = sizeof(COMMCONFIG);
|
||||||
|
comCfg.wVersion = 1;
|
||||||
|
comCfg.dcb.DCBlength = sizeof(DCB);
|
||||||
|
comCfg.dcb.BaudRate = baud;
|
||||||
|
comCfg.dcb.fBinary = 1;
|
||||||
|
comCfg.dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
|
comCfg.dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
comCfg.dcb.ByteSize = 8;
|
||||||
|
|
||||||
|
SetCommConfig(hSerial, &comCfg, sizeof(comCfg));
|
||||||
|
|
||||||
|
const DWORD ctoms = (timeout == -1) ? 30000 : (timeout * 100);
|
||||||
|
COMMTIMEOUTS cto = {ctoms, 0, ctoms, 0, ctoms};
|
||||||
|
SetCommTimeouts(hSerial, &cto);
|
||||||
|
|
||||||
|
if (purge) {
|
||||||
|
PurgeComm(hSerial, PURGE_RXABORT);
|
||||||
|
PurgeComm(hSerial, PURGE_TXABORT);
|
||||||
|
PurgeComm(hSerial, PURGE_RXCLEAR);
|
||||||
|
PurgeComm(hSerial, PURGE_TXCLEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _open_osfhandle((LONG)hSerial, 0);
|
||||||
|
#else
|
||||||
|
int fdDev = open(devpath, O_RDWR | O_CLOEXEC | O_NOCTTY);
|
||||||
|
|
||||||
|
if (unlikely(fdDev == -1))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct termios pattr;
|
||||||
|
tcgetattr(fdDev, &pattr);
|
||||||
|
pattr.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
|
||||||
|
pattr.c_oflag &= ~OPOST;
|
||||||
|
pattr.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
||||||
|
pattr.c_cflag &= ~(CSIZE | PARENB);
|
||||||
|
pattr.c_cflag |= CS8;
|
||||||
|
|
||||||
|
switch (baud) {
|
||||||
|
case 0: break;
|
||||||
|
case 115200: pattr.c_cflag = B115200; break;
|
||||||
|
default:
|
||||||
|
applog(LOG_WARNING, "Unrecognized baud rate: %lu", baud);
|
||||||
|
}
|
||||||
|
pattr.c_cflag |= CREAD | CLOCAL;
|
||||||
|
|
||||||
|
if (timeout >= 0) {
|
||||||
|
pattr.c_cc[VTIME] = (cc_t)timeout;
|
||||||
|
pattr.c_cc[VMIN] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcsetattr(fdDev, TCSANOW, &pattr);
|
||||||
|
if (purge)
|
||||||
|
tcflush(fdDev, TCIOFLUSH);
|
||||||
|
return fdDev;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
_serial_read(int fd, char *buf, size_t bufsiz, char *eol)
|
||||||
|
{
|
||||||
|
ssize_t len, tlen = 0;
|
||||||
|
while (bufsiz) {
|
||||||
|
len = read(fd, buf, eol ? 1 : bufsiz);
|
||||||
|
if (len < 1)
|
||||||
|
break;
|
||||||
|
tlen += len;
|
||||||
|
if (eol && *eol == buf[0])
|
||||||
|
break;
|
||||||
|
buf += len;
|
||||||
|
bufsiz -= len;
|
||||||
|
}
|
||||||
|
return tlen;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FILE*
|
||||||
|
_open_bitstream(const char*path, const char*subdir, const char*filename)
|
||||||
|
{
|
||||||
|
char fullpath[PATH_MAX];
|
||||||
|
strcpy(fullpath, path);
|
||||||
|
strcat(fullpath, "/");
|
||||||
|
if (subdir) {
|
||||||
|
strcat(fullpath, subdir);
|
||||||
|
strcat(fullpath, "/");
|
||||||
|
}
|
||||||
|
strcat(fullpath, filename);
|
||||||
|
return fopen(fullpath, "rb");
|
||||||
|
}
|
||||||
|
#define _open_bitstream(path, subdir) do { \
|
||||||
|
f = _open_bitstream(path, subdir, filename); \
|
||||||
|
if (f) \
|
||||||
|
return f; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define _open_bitstream3(path) do { \
|
||||||
|
_open_bitstream(path, dname); \
|
||||||
|
_open_bitstream(path, "bitstreams"); \
|
||||||
|
_open_bitstream(path, NULL); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
FILE*
|
||||||
|
open_bitstream(const char*dname, const char*filename)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
_open_bitstream3(opt_kernel_path);
|
||||||
|
_open_bitstream3(cgminer_path);
|
||||||
|
_open_bitstream3(".");
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
39
fpgautils.h
Normal file
39
fpgautils.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012 Luke Dashjr
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
|
* Software Foundation; either version 3 of the License, or (at your option)
|
||||||
|
* any later version. See COPYING for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FPGAUTILS_H
|
||||||
|
#define FPGAUTILS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
typedef bool(*detectone_func_t)(const char*);
|
||||||
|
typedef char(*autoscan_func_t)();
|
||||||
|
|
||||||
|
extern char _serial_detect(const char*dnamec, size_t dnamel, detectone_func_t, autoscan_func_t, bool force_autoscan);
|
||||||
|
#define serial_detect_fauto(dname, detectone, autoscan) \
|
||||||
|
_serial_detect(dname ":", sizeof(dname)+1, detectone, autoscan, true)
|
||||||
|
#define serial_detect_auto(dname, detectone, autoscan) \
|
||||||
|
_serial_detect(dname ":", sizeof(dname)+1, detectone, autoscan, false)
|
||||||
|
#define serial_detect(dname, detectone) \
|
||||||
|
_serial_detect(dname ":", sizeof(dname)+1, detectone, NULL, false)
|
||||||
|
extern char serial_autodetect_devserial(detectone_func_t, const char*prodname);
|
||||||
|
extern char serial_autodetect_udev (detectone_func_t, const char*prodname);
|
||||||
|
|
||||||
|
extern int serial_open(const char*devpath, unsigned long baud, signed short timeout, bool purge);
|
||||||
|
extern ssize_t _serial_read(int fd, char *buf, size_t buflen, char*eol);
|
||||||
|
#define serial_read(fd, buf, count) \
|
||||||
|
_serial_read(fd, (char*)(buf), count, NULL)
|
||||||
|
#define serial_read_line(fd, buf, bufsiz, eol) \
|
||||||
|
_serial_read(fd, buf, count, &eol)
|
||||||
|
#define serial_close(fd) close(fd)
|
||||||
|
|
||||||
|
extern FILE*open_bitstream(const char*dname, const char*filename);
|
||||||
|
|
||||||
|
#endif
|
13
libztex.c
13
libztex.c
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "fpgautils.h"
|
||||||
#include "miner.h"
|
#include "miner.h"
|
||||||
#include "libztex.h"
|
#include "libztex.h"
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ static int libztex_configureFpgaHS(struct libztex_device *ztex, const char* firm
|
|||||||
libusb_claim_interface(ztex->hndl, settings[1]);
|
libusb_claim_interface(ztex->hndl, settings[1]);
|
||||||
|
|
||||||
for (tries = 3; tries > 0; tries--) {
|
for (tries = 3; tries > 0; tries--) {
|
||||||
fp = fopen(firmware, "rb");
|
fp = open_bitstream("ztex", firmware);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
|
applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
|
||||||
return -2;
|
return -2;
|
||||||
@ -245,7 +247,7 @@ static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firm
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (tries = 10; tries > 0; tries--) {
|
for (tries = 10; tries > 0; tries--) {
|
||||||
fp = fopen(firmware, "rb");
|
fp = open_bitstream("ztex", firmware);
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
|
applog(LOG_ERR, "%s: failed to read firmware '%s'", ztex->repr, firmware);
|
||||||
return -2;
|
return -2;
|
||||||
@ -316,12 +318,11 @@ static int libztex_configureFpgaLS(struct libztex_device *ztex, const char* firm
|
|||||||
|
|
||||||
int libztex_configureFpga(struct libztex_device *ztex)
|
int libztex_configureFpga(struct libztex_device *ztex)
|
||||||
{
|
{
|
||||||
char buf[256] = "bitstreams/";
|
char buf[256];
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
memset(&buf[11], 0, 245);
|
strcpy(buf, ztex->bitFileName);
|
||||||
strcpy(&buf[11], ztex->bitFileName);
|
strcat(buf, ".bit");
|
||||||
strcpy(&buf[strlen(buf)], ".bit");
|
|
||||||
rv = libztex_configureFpgaHS(ztex, buf, true, 2);
|
rv = libztex_configureFpgaHS(ztex, buf, true, 2);
|
||||||
if (rv != 0)
|
if (rv != 0)
|
||||||
rv = libztex_configureFpgaLS(ztex, buf, true, 2);
|
rv = libztex_configureFpgaLS(ztex, buf, true, 2);
|
||||||
|
1
miner.h
1
miner.h
@ -743,6 +743,7 @@ struct work {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void get_datestamp(char *, struct timeval *);
|
extern void get_datestamp(char *, struct timeval *);
|
||||||
|
extern bool test_nonce(struct work *work, uint32_t nonce);
|
||||||
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
|
||||||
extern void tailsprintf(char *f, const char *fmt, ...);
|
extern void tailsprintf(char *f, const char *fmt, ...);
|
||||||
extern void wlogprint(const char *f, ...);
|
extern void wlogprint(const char *f, ...);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user