Browse Source

Merge branch 'sysfs_autodetect' into bfgminer

Luke Dashjr 13 years ago
parent
commit
69b4aa8c90
6 changed files with 180 additions and 32 deletions
  1. 1 4
      driver-bitforce.c
  2. 1 5
      driver-cairnsmore.c
  3. 1 4
      driver-modminer.c
  4. 149 15
      fpgautils.c
  5. 2 3
      fpgautils.h
  6. 26 1
      miner.c

+ 1 - 4
driver-bitforce.c

@@ -118,10 +118,7 @@ static bool bitforce_detect_one(const char *devpath)
 
 static int bitforce_detect_auto(void)
 {
-	return (serial_autodetect_udev     (bitforce_detect_one, "BitFORCE*SHA256") ?:
-		serial_autodetect_devserial(bitforce_detect_one, "BitFORCE_SHA256") ?:
-		serial_autodetect_ftdi(bitforce_detect_one, "BitFORCE", "SHA256") ?:
-		0);
+	return serial_autodetect(bitforce_detect_one, "BitFORCE", "SHA256");
 }
 
 static void bitforce_detect(void)

+ 1 - 5
driver-cairnsmore.c

@@ -49,11 +49,7 @@ static bool cairnsmore_detect_one(const char *devpath)
 
 static int cairnsmore_detect_auto(void)
 {
-	return
-	serial_autodetect_udev     (cairnsmore_detect_one, "*Cairnsmore1*") ?:
-	serial_autodetect_devserial(cairnsmore_detect_one, "Cairnsmore1") ?:
-	serial_autodetect_ftdi     (cairnsmore_detect_one, "Cairnsmore1", NULL) ?:
-	0;
+	return serial_autodetect(cairnsmore_detect_one, "Cairnsmore1");
 }
 
 static void cairnsmore_detect()

+ 1 - 4
driver-modminer.c

@@ -150,10 +150,7 @@ modminer_detect_one(const char *devpath)
 static int
 modminer_detect_auto()
 {
-	return
-	serial_autodetect_udev     (modminer_detect_one, "*ModMiner*") ?:
-	serial_autodetect_devserial(modminer_detect_one, "BTCFPGA_ModMiner") ?:
-	0;
+	return serial_autodetect(modminer_detect_one, "BTCFPGA", "ModMiner");
 }
 
 static void

+ 149 - 15
fpgautils.c

@@ -10,6 +10,7 @@
 
 #include "config.h"
 
+#include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/types.h>
@@ -55,8 +56,42 @@ enum {
 #include "miner.h"
 #include "fpgautils.h"
 
+#define SEARCH_NEEDLES_BEGIN()  {  \
+	const char *needle;  \
+	bool __cont = false;  \
+	va_list ap;  \
+	va_copy(ap, needles);  \
+	while ( (needle = va_arg(ap, const char *)) )  \
+	{
+
+#define SEARCH_NEEDLES_END(...)  \
+	}  \
+	va_end(ap);  \
+	if (__cont)  \
+	{  \
+		__VA_ARGS__;  \
+	}  \
+}
+
+static inline
+bool search_needles(const char *haystack, va_list needles)
+{
+	bool rv = true;
+	SEARCH_NEEDLES_BEGIN()
+		if (!strstr(haystack, needle))
+		{
+			rv = false;
+			break;
+		}
+	SEARCH_NEEDLES_END()
+	return rv;
+}
+
+#define SEARCH_NEEDLES(haystack)  search_needles(haystack, needles)
+
 #ifdef HAVE_LIBUDEV
-int serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
+static
+int _serial_autodetect_udev(detectone_func_t detectone, va_list needles)
 {
 	struct udev *udev = udev_new();
 	struct udev_enumerate *enumerate = udev_enumerate_new(udev);
@@ -64,7 +99,6 @@ int serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
 	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(
@@ -74,6 +108,10 @@ int serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
 		if (!device)
 			continue;
 
+		const char *model = udev_device_get_property_value(device, "ID_MODEL");
+		if (!(model && SEARCH_NEEDLES(model)))
+			continue;
+
 		const char *devpath = udev_device_get_devnode(device);
 		if (devpath && detectone(devpath))
 			++found;
@@ -86,15 +124,13 @@ int serial_autodetect_udev(detectone_func_t detectone, const char*prodname)
 	return found;
 }
 #else
-int serial_autodetect_udev(__maybe_unused detectone_func_t detectone, __maybe_unused const char*prodname)
-{
-	return 0;
-}
+#	define _serial_autodetect_udev(...)  (0)
 #endif
 
-int serial_autodetect_devserial(__maybe_unused detectone_func_t detectone, __maybe_unused const char*prodname)
-{
 #ifndef WIN32
+static
+int _serial_autodetect_devserial(detectone_func_t detectone, va_list needles)
+{
 	DIR *D;
 	struct dirent *de;
 	const char udevdir[] = "/dev/serial/by-id";
@@ -108,8 +144,9 @@ int serial_autodetect_devserial(__maybe_unused detectone_func_t detectone, __may
 	memcpy(devpath, udevdir, sizeof(udevdir) - 1);
 	devpath[sizeof(udevdir) - 1] = '/';
 	while ( (de = readdir(D)) ) {
-		if (!strstr(de->d_name, prodname))
+		if (!SEARCH_NEEDLES(de->d_name))
 			continue;
+		
 		strcpy(devfile, de->d_name);
 		if (detectone(devpath))
 			++found;
@@ -117,10 +154,93 @@ int serial_autodetect_devserial(__maybe_unused detectone_func_t detectone, __may
 	closedir(D);
 
 	return found;
+}
 #else
-	return 0;
+#	define _serial_autodetect_devserial(...)  (0)
 #endif
+
+#ifndef WIN32
+static
+int _serial_autodetect_sysfs(detectone_func_t detectone, va_list needles)
+{
+	DIR *D, *DS, *DT;
+	FILE *F;
+	struct dirent *de;
+	const char devroot[] = "/sys/bus/usb/devices";
+	const size_t devrootlen = sizeof(devroot) - 1;
+	char devpath[sizeof(devroot) + (NAME_MAX * 3)];
+	char buf[0x100];
+	char *devfile, *upfile;
+	char found = 0;
+	size_t len, len2;
+	
+	D = opendir(devroot);
+	if (!D)
+		return 0;
+	memcpy(devpath, devroot, devrootlen);
+	devpath[devrootlen] = '/';
+	while ( (de = readdir(D)) )
+	{
+		len = strlen(de->d_name);
+		upfile = &devpath[devrootlen + 1];
+		memcpy(upfile, de->d_name, len);
+		devfile = upfile + len;
+		strcpy(devfile, "/product");
+		F = fopen(devpath, "r");
+		if (!(F && fgets(buf, sizeof(buf), F)))
+			continue;
+		
+		if (!SEARCH_NEEDLES(buf))
+			continue;
+		
+		devfile[0] = '\0';
+		DS = opendir(devpath);
+		if (!DS)
+			continue;
+		devfile[0] = '/';
+		++devfile;
+		
+		memcpy(buf, "/dev/", 5);
+		
+		while ( (de = readdir(DS)) )
+		{
+			if (strncmp(de->d_name, upfile, len))
+				continue;
+			
+			len2 = strlen(de->d_name);
+			memcpy(devfile, de->d_name, len2 + 1);
+			
+			DT = opendir(devpath);
+			if (!DT)
+				continue;
+			
+			while ( (de = readdir(DT)) )
+			{
+				if (strncmp(de->d_name, "tty", 3))
+					continue;
+				if (strncmp(&de->d_name[3], "USB", 3) && strncmp(&de->d_name[3], "ACM", 3))
+					continue;
+				
+				strcpy(&buf[5], de->d_name);
+				if (detectone(buf))
+				{
+					++found;
+					closedir(DT);
+					goto nextdev;
+				}
+			}
+			closedir(DT);
+		}
+nextdev:
+		closedir(DS);
+	}
+	closedir(D);
+	
+	return found;
 }
+#else
+#	define _serial_autodetect_sysfs(...)  (0)
+#endif
 
 #ifdef WIN32
 #define LOAD_SYM(sym)  do { \
@@ -130,7 +250,8 @@ int serial_autodetect_devserial(__maybe_unused detectone_func_t detectone, __may
 	}  \
 } while(0)
 
-int serial_autodetect_ftdi(detectone_func_t detectone, const char *needle, const char *needle2)
+static
+int _serial_autodetect_ftdi(detectone_func_t detectone, va_list needles)
 {
 	char devpath[] = "\\\\.\\COMnnnnn";
 	char *devpathnum = &devpath[7];
@@ -174,7 +295,7 @@ int serial_autodetect_ftdi(detectone_func_t detectone, const char *needle, const
 		--i;
 		bufptrs[i][64] = '\0';
 		
-		if (!(strstr(bufptrs[i], needle) && (!needle2 || strstr(bufptrs[i], needle2))))
+		if (!SEARCH_NEEDLES(bufptrs[i]))
 			continue;
 		
 		FT_HANDLE ftHandle;
@@ -197,11 +318,24 @@ out:
 	return found;
 }
 #else
-int serial_autodetect_ftdi(__maybe_unused detectone_func_t detectone, __maybe_unused const char *needle, __maybe_unused const char *needle2)
+#	define _serial_autodetect_ftdi(...)  (0)
+#endif
+
+int _serial_autodetect(detectone_func_t detectone, ...)
 {
-	return 0;
+	int rv;
+	va_list needles;
+	
+	va_start(needles, detectone);
+	rv = (
+		_serial_autodetect_udev     (detectone, needles) ?:
+		_serial_autodetect_sysfs    (detectone, needles) ?:
+		_serial_autodetect_devserial(detectone, needles) ?:
+		_serial_autodetect_ftdi     (detectone, needles) ?:
+		0);
+	va_end(needles);
+	return rv;
 }
-#endif
 
 struct device_api *serial_claim(const char *devpath, struct device_api *api);
 

+ 2 - 3
fpgautils.h

@@ -32,9 +32,8 @@ extern int _serial_detect(struct device_api *api, detectone_func_t, autoscan_fun
 	_serial_detect(api, detectone,     NULL, 0)
 #define noserial_detect(api, autoscan)  \
 	_serial_detect(api, NULL     , autoscan, 0)
-extern int serial_autodetect_devserial(detectone_func_t, const char*prodname);
-extern int serial_autodetect_udev     (detectone_func_t, const char*prodname);
-extern int serial_autodetect_ftdi     (detectone_func_t, const char*needle, const char *needle2);
+extern int _serial_autodetect(detectone_func_t, ...);
+#define serial_autodetect(...)  _serial_autodetect(__VA_ARGS__, NULL)
 
 extern struct device_api *serial_claim(const char *devpath, struct device_api *);
 

+ 26 - 1
miner.c

@@ -34,6 +34,7 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <dirent.h>
 
 #ifndef WIN32
 #include <sys/resource.h>
@@ -629,7 +630,31 @@ tryagain: ;
 	return NULL;
 
 #else
-	return "scan-serial 'all' is not supported on this platform";
+
+	DIR *D;
+	struct dirent *de;
+	const char devdir[] = "/dev";
+	const size_t devdirlen = sizeof(devdir) - 1;
+	char devpath[sizeof(devdir) + NAME_MAX];
+	char *devfile = devpath + devdirlen + 1;
+	
+	D = opendir(devdir);
+	if (!D)
+		return "scan-serial 'all' is not supported on this platform";
+	memcpy(devpath, devdir, devdirlen);
+	devpath[devdirlen] = '/';
+	while ( (de = readdir(D)) ) {
+		if (strncmp(de->d_name, "tty", 3))
+			continue;
+		if (strncmp(&de->d_name[3], "USB", 3) && strncmp(&de->d_name[3], "ACM", 3))
+			continue;
+		
+		strcpy(devfile, de->d_name);
+		applog(LOG_DEBUG, "scan-serial: /dev glob all-adding %s", devpath);
+		string_elist_add(devpath, &scan_devices);
+	}
+	closedir(D);
+
 #endif
 }