Browse Source

Setup BFLSC support

Kano 13 years ago
parent
commit
540f3e89bc
6 changed files with 245 additions and 19 deletions
  1. 4 0
      Makefile.am
  2. 155 6
      api.c
  3. 19 1
      cgminer.c
  4. 23 6
      configure.ac
  5. 1 0
      miner.h
  6. 43 6
      usbutils.c

+ 4 - 0
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

+ 155 - 6
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++) {

+ 19 - 1
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();

+ 23 - 6
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

+ 1 - 0
miner.h

@@ -203,6 +203,7 @@ enum drv_driver {
 	DRIVER_MODMINER,
 	DRIVER_ZTEX,
 	DRIVER_CPU,
+	DRIVER_BFLSC,
 };
 
 enum alive {

+ 43 - 6
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);