From 540f3e89bcaad42856ca852598c196f75c67b117 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 7 Mar 2013 00:00:31 +1100 Subject: [PATCH] Setup BFLSC support --- Makefile.am | 4 ++ api.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++++-- cgminer.c | 20 ++++++- configure.ac | 29 ++++++++-- miner.h | 1 + usbutils.c | 49 ++++++++++++++-- 6 files changed, 245 insertions(+), 19 deletions(-) diff --git a/Makefile.am b/Makefile.am index b7f90637..717d88cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -86,6 +86,10 @@ if NEED_USBUTILS_C cgminer_SOURCES += usbutils.c endif +if HAS_BFLSC +cgminer_SOURCES += driver-bflsc.c +endif + if HAS_BITFORCE cgminer_SOURCES += driver-bitforce.c endif diff --git a/api.c b/api.c index c2e1f7d0..72763f17 100644 --- a/api.c +++ b/api.c @@ -29,6 +29,10 @@ #include "util.h" #include "driver-cpu.h" /* for algo_names[], TODO: re-factor dependency */ +#if defined(USE_BFLSC) +#define HAVE_AN_ASIC 1 +#endif + #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_ZTEX) || defined(USE_MODMINER) #define HAVE_AN_FPGA 1 #endif @@ -135,7 +139,7 @@ static const char GPUSEP = ','; static const char *APIVERSION = "1.25"; static const char *DEAD = "Dead"; -#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) +#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) || defined(HAVE_AN_ASIC) static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; static const char *INIT = "Initialising"; @@ -167,6 +171,9 @@ static const char *DEVICECODE = "" #ifdef HAVE_OPENCL "GPU " #endif +#ifdef USE_BFLSC + "BAS " +#endif #ifdef USE_BITFORCE "BFL " #endif @@ -453,13 +460,19 @@ struct CODES { #ifdef HAVE_OPENCL "%d GPU(s)" #endif -#if defined(HAVE_AN_FPGA) && defined(HAVE_OPENCL) +#if defined(HAVE_AN_ASIC) && defined(HAVE_OPENCL) + " - " +#endif +#ifdef HAVE_AN_ASIC + "%d ASC(s)" +#endif +#if defined(HAVE_AN_FPGA) && (defined(HAVE_OPENCL) || defined(HAVE_AN_ASIC)) " - " #endif #ifdef HAVE_AN_FPGA "%d PGA(s)" #endif -#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA)) +#if defined(WANT_CPUMINE) && (defined(HAVE_OPENCL) || defined(HAVE_AN_ASIC) || defined(HAVE_AN_FPGA)) " - " #endif #ifdef WANT_CPUMINE @@ -468,6 +481,9 @@ struct CODES { }, { SEVERITY_ERR, MSG_NODEVS, PARAM_NONE, "No GPUs" +#ifdef HAVE_AN_ASIC + "/ASCs" +#endif #ifdef HAVE_AN_FPGA "/PGAs" #endif @@ -590,7 +606,7 @@ struct CODES { static int my_thr_id = 0; static bool bye; -#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) +#if defined(HAVE_OPENCL) || defined (HAVE_AN_ASIC) || defined(HAVE_AN_FPGA) static bool ping = true; #endif @@ -1155,6 +1171,48 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson return root; } +#ifdef HAVE_AN_ASIC +static int numascs() +{ + int count = 0; + int i; + + rd_lock(&devices_lock); + for (i = 0; i < total_devices; i++) { +#ifdef USE_BFLSC + if (devices[i]->drv->drv_id == DRIVER_BFLSC) + count++; +#endif + } + rd_unlock(&devices_lock); + return count; +} + +static int ascdevice(int ascid) +{ + int count = 0; + int i; + + rd_lock(&devices_lock); + for (i = 0; i < total_devices; i++) { +#ifdef USE_BFLSC + if (devices[i]->drv->drv_id == DRIVER_BFLSC) + count++; +#endif + if (count == (ascid + 1)) + goto foundit; + } + + rd_unlock(&devices_lock); + return -1; + +foundit: + + rd_unlock(&devices_lock); + return i; +} +#endif + #ifdef HAVE_AN_FPGA static int numpgas() { @@ -1230,6 +1288,9 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p char buf[TMPBUFSIZ]; char buf2[TMPBUFSIZ]; char severity[2]; +#ifdef HAVE_AN_ASIC + int asc; +#endif #ifdef HAVE_AN_FPGA int pga; #endif @@ -1300,6 +1361,9 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p sprintf(buf, codes[i].description, paramid, total_pools - 1); break; case PARAM_DMAX: +#ifdef HAVE_AN_ASIC + asc = numascs(); +#endif #ifdef HAVE_AN_FPGA pga = numpgas(); #endif @@ -1314,6 +1378,9 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p #ifdef HAVE_OPENCL , nDevs #endif +#ifdef HAVE_AN_ASIC + , asc +#endif #ifdef HAVE_AN_FPGA , pga #endif @@ -1394,6 +1461,7 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ char buf[TMPBUFSIZ]; bool io_open; int gpucount = 0; + int asccount = 0; int pgacount = 0; int cpucount = 0; char *adlinuse = (char *)NO; @@ -1415,6 +1483,10 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ gpucount = nDevs; #endif +#ifdef HAVE_AN_ASIC + asccount = numascs(); +#endif + #ifdef HAVE_AN_FPGA pgacount = numpgas(); #endif @@ -1427,6 +1499,7 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ io_open = io_add(io_data, isjson ? COMSTR JSON_MINECONFIG : _MINECONFIG COMSTR); root = api_add_int(root, "GPU Count", &gpucount, false); + root = api_add_int(root, "ASC Count", &asccount, false); root = api_add_int(root, "PGA Count", &pgacount, false); root = api_add_int(root, "CPU Count", &cpucount, false); root = api_add_int(root, "Pool Count", &total_pools, false); @@ -1455,7 +1528,7 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ io_close(io_data); } -#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) +#if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) || defined(HAVE_AN_ASIC) static const char *status2str(enum alive status) { switch (status) { @@ -1546,6 +1619,67 @@ static void gpustatus(struct io_data *io_data, int gpu, bool isjson, bool precom } #endif +#ifdef HAVE_AN_ASIC +static void ascstatus(struct io_data *io_data, int asc, bool isjson, bool precom) +{ + struct api_data *root = NULL; + char buf[TMPBUFSIZ]; + char *enabled; + char *status; + int numasc = numascs(); + + if (numasc > 0 && asc >= 0 && asc < numasc) { + int dev = ascdevice(asc); + if (dev < 0) // Should never happen + return; + + struct cgpu_info *cgpu = get_devices(dev); + float temp = cgpu->temp; + + cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; + + if (cgpu->deven != DEV_DISABLED) + enabled = (char *)YES; + else + enabled = (char *)NO; + + status = (char *)status2str(cgpu->status); + + root = api_add_int(root, "ASC", &asc, false); + root = api_add_string(root, "Name", cgpu->drv->name, false); + root = api_add_int(root, "ID", &(cgpu->device_id), false); + root = api_add_string(root, "Enabled", enabled, false); + root = api_add_string(root, "Status", status, false); + root = api_add_temp(root, "Temperature", &temp, false); + double mhs = cgpu->total_mhashes / total_secs; + root = api_add_mhs(root, "MHS av", &mhs, false); + char mhsname[27]; + sprintf(mhsname, "MHS %ds", opt_log_interval); + root = api_add_mhs(root, mhsname, &(cgpu->rolling), false); + root = api_add_int(root, "Accepted", &(cgpu->accepted), false); + root = api_add_int(root, "Rejected", &(cgpu->rejected), false); + root = api_add_int(root, "Hardware Errors", &(cgpu->hw_errors), false); + root = api_add_utility(root, "Utility", &(cgpu->utility), false); + int last_share_pool = cgpu->last_share_pool_time > 0 ? + cgpu->last_share_pool : -1; + root = api_add_int(root, "Last Share Pool", &last_share_pool, false); + root = api_add_time(root, "Last Share Time", &(cgpu->last_share_pool_time), false); + root = api_add_mhtotal(root, "Total MH", &(cgpu->total_mhashes), false); + root = api_add_int(root, "Diff1 Work", &(cgpu->diff1), false); + root = api_add_diff(root, "Difficulty Accepted", &(cgpu->diff_accepted), false); + root = api_add_diff(root, "Difficulty Rejected", &(cgpu->diff_rejected), false); + root = api_add_diff(root, "Last Share Difficulty", &(cgpu->last_share_diff), false); +#ifdef USE_USBUTILS + root = api_add_bool(root, "No Device", &(cgpu->usbinfo.nodev), false); +#endif + root = api_add_time(root, "Last Valid Work", &(cgpu->last_device_valid_work), false); + + root = print_data(root, buf, isjson, precom); + io_add(io_data, buf); + } +} +#endif + #ifdef HAVE_AN_FPGA static void pgastatus(struct io_data *io_data, int pga, bool isjson, bool precom) { @@ -1660,6 +1794,7 @@ static void devstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma bool io_open = false; int devcount = 0; int numgpu = 0; + int numasc = 0; int numpga = 0; int i; @@ -1667,11 +1802,15 @@ static void devstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma numgpu = nDevs; #endif +#ifdef HAVE_AN_ASIC + numasc = numascs(); +#endif + #ifdef HAVE_AN_FPGA numpga = numpgas(); #endif - if (numgpu == 0 && opt_n_threads == 0 && numpga == 0) { + if (numgpu == 0 && opt_n_threads == 0 && numpga == 0 && numasc == 0) { message(io_data, MSG_NODEVS, 0, NULL, isjson); return; } @@ -1688,6 +1827,16 @@ static void devstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma devcount++; } #endif +#ifdef HAVE_AN_ASIC + if (numasc > 0) { + for (i = 0; i < numasc; i++) { + ascstatus(io_data, i, isjson, isjson && devcount > 0); + + devcount++; + } + } +#endif + #ifdef HAVE_AN_FPGA if (numpga > 0) { for (i = 0; i < numpga; i++) { diff --git a/cgminer.c b/cgminer.c index a6f5fbb9..7fac74b3 100644 --- a/cgminer.c +++ b/cgminer.c @@ -57,7 +57,9 @@ #if defined(USE_BITFORCE) || defined(USE_ICARUS) || defined(USE_MODMINER) # define USE_FPGA +#if defined(USE_ICARUS) # define USE_FPGA_SERIAL +#endif #elif defined(USE_ZTEX) # define USE_FPGA #endif @@ -1116,7 +1118,7 @@ static struct opt_table opt_config_table[] = { opt_set_bool, &use_syslog, "Use system log for output messages (default: standard error)"), #endif -#if defined(HAVE_ADL) || defined(USE_BITFORCE) || defined(USE_MODMINER) +#if defined(HAVE_ADL) || defined(USE_BITFORCE) || defined(USE_MODMINER) || defined(USE_BFLSC) OPT_WITH_ARG("--temp-cutoff", set_temp_cutoff, opt_show_intval, &opt_cutofftemp, "Temperature where a device will be automatically disabled, one value or comma separated list"), @@ -1316,6 +1318,9 @@ extern const char *opt_argv0; static char *opt_verusage_and_exit(const char *extra) { printf("%s\nBuilt with " +#ifdef USE_BFLSC + "bflsc " +#endif #ifdef HAVE_OPENCL "GPU " #endif @@ -6608,6 +6613,10 @@ struct device_drv cpu_drv = { }; #endif +#ifdef USE_BFLSC +extern struct device_drv bflsc_drv; +#endif + #ifdef USE_BITFORCE extern struct device_drv bitforce_drv; #endif @@ -6873,6 +6882,10 @@ static void *hotplug_thread(void __maybe_unused *userdata) new_devices = 0; new_threads = 0; +#ifdef USE_BFLSC + bflsc_drv.drv_detect(); +#endif + #ifdef USE_BITFORCE bitforce_drv.drv_detect(); #endif @@ -7113,6 +7126,11 @@ int main(int argc, char *argv[]) icarus_drv.drv_detect(); #endif +#ifdef USE_BFLSC + if (!opt_scrypt) + bflsc_drv.drv_detect(); +#endif + #ifdef USE_BITFORCE if (!opt_scrypt) bitforce_drv.drv_detect(); diff --git a/configure.ac b/configure.ac index a14ef76b..068910d4 100644 --- a/configure.ac +++ b/configure.ac @@ -203,10 +203,21 @@ fi AM_CONDITIONAL([HAS_SCRYPT], [test x$scrypt = xyes]) +bflsc="no" + +AC_ARG_ENABLE([bflsc], + [AC_HELP_STRING([--enable-bflsc],[Compile support for BFL ASICs (default disabled)])], + [bflsc=$enableval] + ) +if test "x$bflsc" = xyes; then + AC_DEFINE([USE_BFLSC], [1], [Defined to 1 if BFL ASIC support is wanted]) +fi +AM_CONDITIONAL([HAS_BFLSC], [test x$bflsc = xyes]) + bitforce="no" AC_ARG_ENABLE([bitforce], - [AC_HELP_STRING([--enable-bitforce],[Compile support for BitForce FPGAs(default disabled)])], + [AC_HELP_STRING([--enable-bitforce],[Compile support for BitForce FPGAs (default disabled)])], [bitforce=$enableval] ) if test "x$bitforce" = xyes; then @@ -272,13 +283,13 @@ else fi AM_CONDITIONAL([NEED_FPGAUTILS], [test x$icarus$bitforce$modminer$ztex != xnononono]) -AM_CONDITIONAL([NEED_USBUTILS_C], [test x$bitforce$modminer != xnono]) +AM_CONDITIONAL([NEED_USBUTILS_C], [test x$bitforce$modminer$bflsc != xnonono]) AM_CONDITIONAL([HAVE_CURSES], [test x$curses = xyes]) AM_CONDITIONAL([WANT_JANSSON], [test x$request_jansson = xtrue]) AM_CONDITIONAL([HAVE_WINDOWS], [test x$have_win32 = xtrue]) AM_CONDITIONAL([HAVE_x86_64], [test x$have_x86_64 = xtrue]) -if test "x$bitforce$modminer" != xnono; then +if test "x$bitforce$modminer$bflsc" != xnonono; then AC_DEFINE([USE_USBUTILS], [1], [Defined to 1 if usbutils support required]) fi @@ -347,7 +358,7 @@ AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno]) PKG_PROG_PKG_CONFIG() -if test "x$ztex$modminer$bitforce" != xnonono; then +if test "x$ztex$modminer$bitforce$bflsc" != xnononono; then case $target in *-*-freebsd*) LIBUSB_LIBS="-lusb" @@ -464,14 +475,14 @@ if test "x$opencl" != xno; then else echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED" - if test "x$cpumining$bitforce$icarus$ztex$modminer" = xnonononono; then + if test "x$cpumining$bitforce$icarus$ztex$modminer$bflsc" = xnononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" fi else echo " OpenCL...............: Detection overrided. GPU mining support DISABLED" - if test "x$cpumining$bitforce$icarus$ztex$modminer" = xnonononono; then + if test "x$cpumining$bitforce$icarus$ztex$modminer$bflsc" = xnononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" @@ -488,6 +499,12 @@ else fi echo +if test "x$bflsc" = xyes; then + echo " BFL.ASICs............: Enabled" +else + echo " BFL.ASICs............: Disabled" +fi + if test "x$bitforce" = xyes; then echo " BitForce.FPGAs.......: Enabled" else diff --git a/miner.h b/miner.h index 2d4f7ff0..6f1b1650 100644 --- a/miner.h +++ b/miner.h @@ -203,6 +203,7 @@ enum drv_driver { DRIVER_MODMINER, DRIVER_ZTEX, DRIVER_CPU, + DRIVER_BFLSC, }; enum alive { diff --git a/usbutils.c b/usbutils.c index 06cb9c1f..52226851 100644 --- a/usbutils.c +++ b/usbutils.c @@ -20,8 +20,8 @@ (err) == LIBUSB_ERROR_PIPE || \ (err) == LIBUSB_ERROR_OTHER) -#ifdef USE_ICARUS -#define DRV_ICARUS 1 +#ifdef USE_BFLSC +#define DRV_BFLSC 1 #endif #ifdef USE_BITFORCE @@ -32,6 +32,10 @@ #define DRV_MODMINER 3 #endif +#ifdef USE_ICARUS +#define DRV_ICARUS 4 +#endif + #define DRV_LAST -1 #define USB_CONFIG 1 @@ -40,13 +44,23 @@ #define EPO(x) (LIBUSB_ENDPOINT_OUT | (unsigned char)(x)) #ifdef WIN32 +#define BFLSC_TIMEOUT_MS 500 #define BITFORCE_TIMEOUT_MS 500 #define MODMINER_TIMEOUT_MS 200 #else +#define BFLSC_TIMEOUT_MS 200 #define BITFORCE_TIMEOUT_MS 200 #define MODMINER_TIMEOUT_MS 100 #endif +#ifdef USE_BFLSC +// N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 +static struct usb_endpoints bas_eps[] = { + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(2), 0 } +}; +#endif + #ifdef USE_BITFORCE // N.B. transfer size is 512 with USB2.0, but only 64 with USB1.1 static struct usb_endpoints bfl_eps[] = { @@ -71,6 +85,19 @@ static struct usb_find_devices find_dev[] = { { DRV_ICARUS, "CM1", 0x067b, 0x0230, false, EPI(0), EPO(0), 1 }, #endif */ +#ifdef USE_BFLSC + { + .drv = DRV_BFLSC, + .name = "BAS", + .idVendor = 0x0403, + .idProduct = 0x6014, + .kernel = 0, + .config = 1, + .interface = 0, + .timeout = BFLSC_TIMEOUT_MS, + .epcount = ARRAY_SIZE(bas_eps), + .eps = bas_eps }, +#endif #ifdef USE_BITFORCE { .drv = DRV_BITFORCE, @@ -100,18 +127,22 @@ static struct usb_find_devices find_dev[] = { { DRV_LAST, NULL, 0, 0, 0, 0, 0, 0, 0, NULL } }; -#ifdef USE_BITFORCE -extern struct device_drv bitforce_drv; +#ifdef USE_BFLSC +extern struct device_drv bflsc_drv; #endif -#ifdef USE_ICARUS -extern struct device_drv icarus_drv; +#ifdef USE_BITFORCE +extern struct device_drv bitforce_drv; #endif #ifdef USE_MODMINER extern struct device_drv modminer_drv; #endif +#ifdef USE_ICARUS +extern struct device_drv icarus_drv; +#endif + #define STRBUFLEN 256 static const char *BLANK = ""; @@ -1130,6 +1161,11 @@ static struct usb_find_devices *usb_check_each(int drvnum, struct device_drv *dr static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv, __maybe_unused struct libusb_device *dev) { +#ifdef USE_BFLSC + if (drv->drv_id == DRIVER_BFLSC) + return usb_check_each(DRV_BFLSC, drv, dev); +#endif + #ifdef USE_BITFORCE if (drv->drv_id == DRIVER_BITFORCE) return usb_check_each(DRV_BITFORCE, drv, dev); @@ -1534,6 +1570,7 @@ void usb_cleanup() for (i = 0; i < total_devices; i++) { cgpu = get_devices(i); switch (cgpu->drv->drv_id) { + case DRIVER_BFLSC: case DRIVER_BITFORCE: case DRIVER_MODMINER: release_cgpu(cgpu);