Browse Source

Merge branch 'uniscan2' into bfgminer

Luke Dashjr 12 years ago
parent
commit
407d602403
14 changed files with 129 additions and 80 deletions
  1. 4 4
      README
  2. 1 1
      driver-bigpic.c
  3. 1 1
      driver-bitforce.c
  4. 1 1
      driver-cairnsmore.c
  5. 1 6
      driver-cpu.c
  6. 1 1
      driver-erupter.c
  7. 1 1
      driver-littlefury.c
  8. 1 1
      driver-modminer.c
  9. 1 5
      driver-opencl.c
  10. 16 1
      fpgautils.c
  11. 22 0
      lowl-usb.c
  12. 17 1
      lowlevel.c
  13. 1 0
      lowlevel.h
  14. 61 57
      miner.c

+ 4 - 4
README

@@ -213,7 +213,7 @@ Options for both config file and command line:
 --compact           Use compact display without per device statistics
 --debug|-D          Enable debug output
 --debuglog          Enable debug logging
---device|-d <arg>   Select device to use, one value, range and/or comma separated (e.g. 0-2,4) default: all
+--device|-d <arg>   Enable only devices matching pattern (default: all)
 --disable-rejecting Automatically disable pools that continually reject shares
 --http-port <arg>   Port number to listen on for HTTP getwork miners (-1 means disabled) (default: -1)
 --expiry|-E <arg>   Upper bound on how many seconds after getting work we consider a share from it stale (w/o longpoll active) (default: 120)
@@ -806,9 +806,9 @@ Windows drivers:
 
 Q: I ran cgminer, and now BFGMiner doesn't work!
 A: cgminer has its own non-standard implementations of the drivers for most USB
-devices, and disables the official drivers (on Windows, you did this manually
-using Zadig). Before you can use BFGMiner, you will need to restore the original
-driver. With Linux, usually rebooting or re-plugging the device is sufficient.
+devices, and requires you to replace the official drivers with WinUSB on Windows
+(usually using Zadig). Before you can use BFGMiner, you will need to restore the
+original driver.
 
 Q: On Linux I can see the /dev/ttyUSB* devices for my ICA/BFL/MMQ FPGA, but
 BFGMiner can't mine on them

+ 1 - 1
driver-bigpic.c

@@ -35,7 +35,7 @@ BFG_REGISTER_DRIVER(bigpic_drv)
 static
 bool bigpic_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "Bitfury", "BF1");
+	return lowlevel_match_product(info, "Bitfury", "BF1");
 }
 
 //------------------------------------------------------------------------------

+ 1 - 1
driver-bitforce.c

@@ -169,7 +169,7 @@ int bitforce_chips_to_plan_for(int parallel, int chipcount) {
 static
 bool bitforce_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "BitFORCE", "SHA256");
+	return lowlevel_match_product(info, "BitFORCE", "SHA256");
 }
 
 static bool bitforce_detect_one(const char *devpath)

+ 1 - 1
driver-cairnsmore.c

@@ -33,7 +33,7 @@ BFG_REGISTER_DRIVER(cairnsmore_drv)
 static
 bool cairnsmore_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "Cairnsmore1");
+	return lowlevel_match_product(info, "Cairnsmore1");
 }
 
 static bool cairnsmore_detect_one(const char *devpath)

+ 1 - 6
driver-cpu.c

@@ -776,12 +776,7 @@ static int cpu_autodetect()
 
 static void cpu_detect()
 {
-	if ((opt_n_threads < 0 || !forced_n_threads)
-	 && ((total_devices || total_devices_new) && !opt_usecpu))
-		// If there are any other devices, only act if the user has explicitly enabled it
-		noserial_detect_manual(&cpu_drv, cpu_autodetect);
-	else
-		noserial_detect(&cpu_drv, cpu_autodetect);
+	noserial_detect_manual(&cpu_drv, cpu_autodetect);
 }
 
 static pthread_mutex_t cpualgo_lock;

+ 1 - 1
driver-erupter.c

@@ -45,7 +45,7 @@ static bool _erupter_detect_one(const char *devpath, struct device_drv *drv)
 static
 bool erupter_emerald_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "Block", "Erupter", "Emerald");
+	return lowlevel_match_product(info, "Block", "Erupter", "Emerald");
 }
 
 static bool erupter_emerald_detect_one(const char *devpath)

+ 1 - 1
driver-littlefury.c

@@ -226,7 +226,7 @@ bool littlefury_txrx(struct spi_port *port)
 static
 bool littlefury_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "LittleFury");
+	return lowlevel_match_product(info, "LittleFury");
 }
 
 static

+ 1 - 1
driver-modminer.c

@@ -104,7 +104,7 @@ static const char NOOP[] = MODMINER_PING "\xff\xff\xff\xff\xff\xff\xff\xff\xff\x
 static
 bool modminer_lowl_match(const struct lowlevel_device_info * const info)
 {
-	return lowlevel_match_lowlproduct(info, &lowl_vcom, "ModMiner");
+	return lowlevel_match_product(info, "ModMiner");
 }
 
 static bool

+ 1 - 5
driver-opencl.c

@@ -1424,11 +1424,7 @@ static int opencl_autodetect()
 
 static void opencl_detect()
 {
-	if (total_devices || total_devices_new)
-		// If there are any other devices, only act if the user has explicitly enabled OpenCL
-		noserial_detect_manual(&opencl_api, opencl_autodetect);
-	else
-		noserial_detect(&opencl_api, opencl_autodetect);
+	noserial_detect_manual(&opencl_api, opencl_autodetect);
 }
 
 static void reinit_opencl_device(struct cgpu_info *gpu)

+ 16 - 1
fpgautils.c

@@ -647,10 +647,19 @@ extern void _vcom_devinfo_scan_querydosdevice(struct lowlevel_device_info **);
 extern void _vcom_devinfo_scan_lsdev(struct lowlevel_device_info **);
 #endif
 
+extern bool lowl_usb_attach_kernel_driver(const struct lowlevel_device_info *);
+
 bool vcom_lowl_probe_wrapper(const struct lowlevel_device_info * const info, detectone_func_t detectone)
 {
 	if (info->lowl != &lowl_vcom)
+	{
+		if (info->lowl == &lowl_usb)
+		{
+			if (lowl_usb_attach_kernel_driver(info))
+				bfg_need_detect_rescan = true;
+		}
 		return false;
+	}
 	detectone_meta_info = (struct detectone_meta_info_t){
 		.manufacturer = info->manufacturer,
 		.product = info->product,
@@ -671,7 +680,12 @@ bool _serial_autodetect_found_cb(struct lowlevel_device_info * const devinfo, vo
 	}
 	if (devinfo->lowl != &lowl_vcom)
 	{
-		if (devinfo->lowl != &lowl_usb)
+		if (devinfo->lowl == &lowl_usb)
+		{
+			if (lowl_usb_attach_kernel_driver(devinfo))
+				bfg_need_detect_rescan = true;
+		}
+		else
 			applog(LOG_WARNING, "Non-VCOM %s (%s) matched", devinfo->path, devinfo->devid);
 		return false;
 	}
@@ -736,6 +750,7 @@ struct lowlevel_device_info *vcom_devinfo_scan()
 	{
 		LL_PREPEND(devinfo_list, devinfo);
 	}
+	HASH_CLEAR(hh, devinfo_hash);
 	
 	return devinfo_list;
 }

+ 22 - 0
lowl-usb.c

@@ -9,6 +9,7 @@
 
 #include "config.h"
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -108,6 +109,27 @@ struct lowlevel_device_info *usb_devinfo_scan()
 	return devinfo_list;
 }
 
+bool lowl_usb_attach_kernel_driver(const struct lowlevel_device_info * const info)
+{
+	libusb_device * const dev = info->lowl_data;
+	libusb_device_handle *devh;
+	bool rv = false;
+	
+	if (libusb_open(dev, &devh))
+		return false;
+	
+	if (libusb_kernel_driver_active(devh, 0) == 0)
+		if (!libusb_attach_kernel_driver(devh, 0))
+		{
+			applog(LOG_DEBUG, "Reattaching kernel driver for %s", info->devid);
+			rv = true;
+		}
+	
+	libusb_close(devh);
+	
+	return rv;
+}
+
 struct libusb_device_handle *lowl_usb_open(struct lowlevel_device_info * const info)
 {
 	libusb_device * const dev = info->lowl_data;

+ 17 - 1
lowlevel.c

@@ -59,11 +59,16 @@ void lowlevel_scan_free()
 		return;
 	
 	struct lowlevel_device_info *info, *tmp;
+	struct lowlevel_device_info *info2, *tmp2;
 	
 	LL_FOREACH_SAFE(devinfo_list, info, tmp)
 	{
 		LL_DELETE(devinfo_list, info);
-		lowlevel_devinfo_free(info);
+		LL_FOREACH_SAFE2(info, info2, tmp2, same_devid_next)
+		{
+			LL_DELETE(info, info2);
+			lowlevel_devinfo_free(info2);
+		}
 	}
 }
 
@@ -98,8 +103,19 @@ struct lowlevel_device_info *lowlevel_scan()
 	LL_CONCAT(devinfo_list, devinfo_mid_list);
 #endif
 	
+	struct lowlevel_device_info *devinfo_same_prev_ht = NULL, *devinfo_same_list;
 	LL_FOREACH(devinfo_list, devinfo_mid_list)
 	{
+		// Check for devid overlapping, and build a secondary linked list for them, only including the devid in the main list once (high level to low level)
+		HASH_FIND_STR(devinfo_same_prev_ht, devinfo_mid_list->devid, devinfo_same_list);
+		if (devinfo_same_list)
+		{
+			HASH_DEL(devinfo_same_prev_ht, devinfo_same_list);
+			LL_DELETE(devinfo_list, devinfo_same_list);
+		}
+		LL_PREPEND2(devinfo_same_list, devinfo_mid_list, same_devid_next);
+		HASH_ADD_KEYPTR(hh, devinfo_same_prev_ht, devinfo_mid_list->devid, strlen(devinfo_mid_list->devid), devinfo_same_list);
+		
 		applog(LOG_DEBUG, "%s: Found %s device at %s (path=%s, vid=%04x, pid=%04x, manuf=%s, prod=%s, serial=%s)",
 		       __func__,
 		       devinfo_mid_list->lowl->dname,

+ 1 - 0
lowlevel.h

@@ -30,6 +30,7 @@ struct lowlevel_device_info {
 	void *lowl_data;
 	
 	struct lowlevel_device_info *next;
+	struct lowlevel_device_info *same_devid_next;
 	UT_hash_handle hh;
 	pthread_t probe_pth;
 	int ref;

+ 61 - 57
miner.c

@@ -1064,12 +1064,6 @@ static char *add_serial(const char *arg)
 	return NULL;
 }
 
-static char *compat_disable_gpu(__maybe_unused void *arg)
-{
-	string_elist_add("opencl:noauto", &scan_devices);
-	return NULL;
-}
-
 static
 char *opt_string_elist_add(const char *arg, struct string_elist **elist)
 {
@@ -1163,8 +1157,7 @@ static char *set_devices(char *arg)
 	} else
 		return "Invalid device parameters";
 
-	for (const char *item = strtok(arg, ","); item; item = strtok(NULL, ","))
-		string_elist_add(item, &opt_devices_enabled_list);
+	string_elist_add(arg, &opt_devices_enabled_list);
 
 	return NULL;
 }
@@ -1788,11 +1781,7 @@ static struct opt_table opt_config_table[] = {
 			"Verbose dump of device protocol-level activities"),
 	OPT_WITH_ARG("--device|-d",
 		     set_devices, NULL, NULL,
-	             "Select device to use, one value, range and/or comma separated (e.g. 0-2,4) default: all"),
-	OPT_WITHOUT_ARG("--disable-gpu|-G",
-			compat_disable_gpu, NULL,
-			opt_hidden
-	),
+	             "Enable only devices matching pattern (default: all)"),
 	OPT_WITHOUT_ARG("--disable-rejecting",
 			opt_set_bool, &opt_disable_pool,
 			"Automatically disable pools that continually reject shares"),
@@ -6099,7 +6088,8 @@ static void json_escape_free()
 	}
 }
 
-static char *json_escape(char *str)
+static
+char *json_escape(const char *str)
 {
 	struct JE *jeptr;
 	char *buf, *ptr;
@@ -6176,6 +6166,24 @@ void _write_config_temps(FILE *fcfg, const char *configname, size_t settingoffse
 #define write_config_temps(fcfg, configname, settingname)  \
 	_write_config_temps(fcfg, configname, offsetof(struct cgpu_info, settingname), offsetof(struct cgpu_info, settingname ## _default))
 
+static
+void _write_config_string_elist(FILE *fcfg, const char *configname, struct string_elist * const elist)
+{
+	if (!elist)
+		return;
+	
+	static struct string_elist *entry;
+	fprintf(fcfg, ",\n\"%s\" : [", configname);
+	bool first = true;
+	DL_FOREACH(elist, entry)
+	{
+		const char * const s = entry->string;
+		fprintf(fcfg, "%s\n\t\"%s\"", first ? "" : ",", json_escape(s));
+		first = false;
+	}
+	fprintf(fcfg, "\n]");
+}
+
 void write_config(FILE *fcfg)
 {
 	int i;
@@ -6356,24 +6364,9 @@ void write_config(FILE *fcfg)
 	if (opt_socks_proxy && *opt_socks_proxy)
 		fprintf(fcfg, ",\n\"socks-proxy\" : \"%s\"", json_escape(opt_socks_proxy));
 	
-	{
-		for (i = 0; i < total_devices; ++i)
-			if (devices[i]->deven == DEV_DISABLED)
-			{
-				// At least one device is in fact disabled, so include device params
-				fprintf(fcfg, ",\n\"device\" : [");
-				bool first = true;
-				for (i = 0; i < total_devices; ++i)
-					if (devices[i]->deven != DEV_DISABLED)
-					{
-						fprintf(fcfg, "%s\n\t%d", first ? "" : ",", i);
-						first = false;
-					}
-				fprintf(fcfg, "\n]");
-				
-				break;
-			}
-	}
+	_write_config_string_elist(fcfg, "scan-serial", scan_devices);
+	_write_config_string_elist(fcfg, "device", opt_devices_enabled_list);
+	_write_config_string_elist(fcfg, "set-device", opt_set_device_list);
 	
 	if (opt_api_allow)
 		fprintf(fcfg, ",\n\"api-allow\" : \"%s\"", json_escape(opt_api_allow));
@@ -10394,11 +10387,12 @@ bool _probe_device_internal(struct lowlevel_device_info * const info, const char
 static
 void *probe_device_thread(void *p)
 {
-	struct lowlevel_device_info * const info = p;
+	struct lowlevel_device_info * const infolist = p;
+	struct lowlevel_device_info *info = infolist;
 	
 	{
 		char threadname[5 + strlen(info->devid) + 1];
-		sprintf(threadname, "probe%s", info->devid);
+		sprintf(threadname, "probe_%s", info->devid);
 		RenameThread(threadname);
 	}
 	
@@ -10417,11 +10411,14 @@ void *probe_device_thread(void *p)
 		if (!colon)
 			continue;
 		const char * const ser = &colon[1];
-		if (!_probe_device_match(info, ser))
-			continue;
-		const size_t dnamelen = (colon - dname);
-		if (_probe_device_internal(info, dname, dnamelen))
-			return NULL;
+		LL_FOREACH2(infolist, info, same_devid_next)
+		{
+			if (!_probe_device_match(info, ser))
+				continue;
+			const size_t dnamelen = (colon - dname);
+			if (_probe_device_internal(info, dname, dnamelen))
+				return NULL;
+		}
 	}
 	
 	// probe driver(s) with auto enabled and matching VID/PID/Product/etc of device
@@ -10448,41 +10445,48 @@ void *probe_device_thread(void *p)
 				break;
 		}
 		
-		if (doauto)
+		if (doauto && drv->lowl_match)
 		{
-			if (!(drv->lowl_match && drv->lowl_match(info)))
-				continue;
-			if (drv->lowl_probe(info))
-				return NULL;
+			LL_FOREACH2(infolist, info, same_devid_next)
+			{
+				if (!drv->lowl_match(info))
+					continue;
+				if (drv->lowl_probe(info))
+					return NULL;
+			}
 		}
 	}
 	
 	// probe driver(s) with 'all' enabled
-	bool allall = false;
 	DL_FOREACH_SAFE(scan_devices, sd_iter, sd_tmp)
 	{
 		const char * const dname = sd_iter->string;
 		const char * const colon = strchr(dname, ':');
 		if (!colon)
 		{
-			if ((!strcasecmp(dname, "all")) || _probe_device_match(info, dname))
-				allall = true;
+			LL_FOREACH2(infolist, info, same_devid_next)
+			{
+				if ((!strcasecmp(dname, "all")) || _probe_device_match(info, dname))
+				{
+					BFG_FOREACH_DRIVER_BY_PRIORITY(dreg, dreg_tmp)
+					{
+						const struct device_drv * const drv = dreg->drv;
+						if (!drv->lowl_probe)
+							continue;
+						if (drv->lowl_probe(info))
+							return NULL;
+					}
+					break;
+				}
+			}
 			continue;
 		}
 		if (strcasecmp(&colon[1], "all"))
 			continue;
 		const size_t dnamelen = (colon - dname);
-		if (_probe_device_internal(info, dname, dnamelen))
-			return NULL;
-	}
-	if (allall)
-	{
-		BFG_FOREACH_DRIVER_BY_PRIORITY(dreg, dreg_tmp)
+		LL_FOREACH2(infolist, info, same_devid_next)
 		{
-			const struct device_drv * const drv = dreg->drv;
-			if (!drv->lowl_probe)
-				continue;
-			if (drv->lowl_probe(info))
+			if (_probe_device_internal(info, dname, dnamelen))
 				return NULL;
 		}
 	}