Commit be8cadbc46f0d25e912df851f89142f54cbc66ea

Kano 2013-03-04T17:26:11

Hotplug - allow setting interval via --hotplug or API

diff --git a/API-README b/API-README
index 567f165..de6233c 100644
--- a/API-README
+++ b/API-README
@@ -361,6 +361,14 @@ The list of requests - a (*) means it requires privileged access - and replies a
                               shown on the cgminer display like is normally displayed
                               on exit.
 
+ hotplug|N (*) none           There is no reply section just the STATUS section
+                              stating that the hotplug setting succeeded
+                              If the code is not compiled with hotplug in it, the
+                              the warning reply will be 'Hotplug is not available'
+                              If N=0 then hotplug will be disabled
+                              If N>0 && <=9999, then hotplug will check for new
+                              devices every N seconds
+
 When you enable, disable or restart a GPU or PGA, you will also get Thread messages
 in the cgminer status window
 
@@ -416,8 +424,12 @@ Feature Changelog for external applications using the API:
 
 API V1.25
 
+Added API commands:
+ 'hotplug'
+
 Modified API commands:
  'devs' 'gpu' and 'pga' - add 'Last Valid Work'
+ 'config' - add 'Hotplug'
 
 ----------
 
diff --git a/api.c b/api.c
index 44cbf7f..bb14105 100644
--- a/api.c
+++ b/api.c
@@ -149,6 +149,8 @@ static const char *UNKNOWN = "Unknown";
 static const char *DYNAMIC = _DYNAMIC;
 #endif
 
+static __maybe_unused const char *NONE = "None";
+
 static const char *YES = "Y";
 static const char *NO = "N";
 static const char *NULLSTR = "(null)";
@@ -392,6 +394,11 @@ static const char *JSON_PARAMETER = "parameter";
 #define MSG_ZERSUM 96
 #define MSG_ZERNOSUM 97
 #define MSG_USBNODEV 98
+#define MSG_INVHPLG 99
+#define MSG_HOTPLUG 100
+#define MSG_DISHPLG 101
+#define MSG_NOHPLG 102
+#define MSG_MISHPLG 102
 
 enum code_severity {
 	SEVERITY_ERR,
@@ -421,6 +428,7 @@ enum code_parameters {
 	PARAM_BOTH,
 	PARAM_BOOL,
 	PARAM_SET,
+	PARAM_INT,
 	PARAM_NONE
 };
 
@@ -572,6 +580,11 @@ struct CODES {
 #if defined(USE_MODMINER) || defined(USE_BITFORCE)
  { SEVERITY_ERR,   MSG_USBNODEV, PARAM_PGA,	"PGA%d has no device" },
 #endif
+ { SEVERITY_ERR,   MSG_INVHPLG,	PARAM_STR,	"Invalid value for hotplug (%s) must be 0..9999" },
+ { SEVERITY_SUCC,  MSG_HOTPLUG,	PARAM_INT,	"Hotplug check set to %ds" },
+ { SEVERITY_SUCC,  MSG_DISHPLG,	PARAM_NONE,	"Hotplug disabled" },
+ { SEVERITY_WARN,  MSG_NOHPLG,	PARAM_NONE,	"Hotplug is not available" },
+ { SEVERITY_ERR,   MSG_MISHPLG,	PARAM_NONE,	"Missing hotplug parameter" },
  { SEVERITY_FAIL, 0, 0, NULL }
 };
 
@@ -1254,6 +1267,7 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p
 				case PARAM_PGA:
 				case PARAM_CPU:
 				case PARAM_PID:
+				case PARAM_INT:
 					sprintf(buf, codes[i].description, paramid);
 					break;
 				case PARAM_POOL:
@@ -1426,6 +1440,14 @@ static void minerconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __
 	root = api_add_int(root, "ScanTime", &opt_scantime, false);
 	root = api_add_int(root, "Queue", &opt_queue, false);
 	root = api_add_int(root, "Expiry", &opt_expiry, false);
+#if defined(USE_MODMINER) || defined(USE_BITFORCE)
+	if (hotplug_time == 0)
+		root = api_add_const(root, "Hotplug", DISABLED, false);
+	else
+		root = api_add_int(root, "Hotplug", &hotplug_time, false);
+#else
+	root = api_add_const(root, "Hotplug", NONE, false);
+#endif
 
 	root = print_data(root, buf, isjson, false);
 	io_add(io_data, buf);
@@ -3308,6 +3330,34 @@ static void dozero(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *p
 		message(io_data, MSG_ZERNOSUM, 0, all ? "All" : "BestShare", isjson);
 }
 
+static void dohotplug(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
+{
+#if defined(USE_MODMINER) || defined(USE_BITFORCE)
+	int value;
+
+	if (param == NULL || *param == '\0') {
+		message(io_data, MSG_MISHPLG, 0, NULL, isjson);
+		return;
+	}
+
+	value = atoi(param);
+	if (value < 0 || value > 9999) {
+		message(io_data, MSG_INVHPLG, 0, param, isjson);
+		return;
+	}
+
+	hotplug_time = value;
+
+	if (value)
+		message(io_data, MSG_HOTPLUG, value, NULL, isjson);
+	else
+		message(io_data, MSG_DISHPLG, 0, NULL, isjson);
+#else
+	message(io_data, MSG_NOHPLG, 0, NULL, isjson);
+	return;
+#endif
+}
+
 static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group);
 
 struct CMDS {
@@ -3368,6 +3418,7 @@ struct CMDS {
 	{ "pgaset",		pgaset,		true },
 #endif
 	{ "zero",		dozero,		true },
+	{ "hotplug",		dohotplug,	true },
 	{ NULL,			NULL,		false }
 };
 
diff --git a/cgminer.c b/cgminer.c
index 5300e1e..2a51afe 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -165,6 +165,7 @@ bool hotplug_mode;
 static int new_devices;
 static int new_threads;
 static int start_devices;
+int hotplug_time = 5;
 
 #ifdef HAVE_LIBUSB
 pthread_mutex_t cgusb_lock;
@@ -984,6 +985,14 @@ static struct opt_table opt_config_table[] = {
 		     set_intensity, NULL, NULL,
 		     "Intensity of GPU scanning (d or " _MIN_INTENSITY_STR " -> " _MAX_INTENSITY_STR ", default: d to maintain desktop interactivity)"),
 #endif
+	OPT_WITH_ARG("--hotplug",
+		     set_int_0_to_9999, NULL, &hotplug_time,
+#if defined(USE_MODMINER) || defined(USE_BITFORCE)
+		     "Seconds between hotplug checks (0 means never check)"
+#else
+		     opt_hidden
+#endif
+		    ),
 #if defined(HAVE_OPENCL) || defined(HAVE_MODMINER)
 	OPT_WITH_ARG("--kernel-path|-K",
 		     opt_set_charp, opt_show_charp, &opt_kernel_path,
@@ -6853,24 +6862,31 @@ static void *hotplug_thread(void __maybe_unused *userdata)
 
 	hotplug_mode = true;
 
-	while (0x2a) {
-		nmsleep(5000);
+	nmsleep(5000);
 
+	while (0x2a) {
 // Version 0.1 just add the devices on - worry about using nodev later
 
-		new_devices = 0;
-		new_threads = 0;
+		if (hotplug_time == 0)
+			nmsleep(5000);
+		else {
+			new_devices = 0;
+			new_threads = 0;
 
 #ifdef USE_BITFORCE
-		bitforce_drv.drv_detect();
+			bitforce_drv.drv_detect();
 #endif
 
 #ifdef USE_MODMINER
-		modminer_drv.drv_detect();
+			modminer_drv.drv_detect();
 #endif
 
-		if (new_devices)
-			hotplug_process();
+			if (new_devices)
+				hotplug_process();
+
+			// hotplug_time >0 && <=9999
+			nmsleep(hotplug_time * 1000);
+		}
 	}
 
 	return NULL;
diff --git a/miner.h b/miner.h
index a6872e4..07918c6 100644
--- a/miner.h
+++ b/miner.h
@@ -801,6 +801,7 @@ extern void add_pool_details(struct pool *pool, bool live, char *url, char *user
 #endif
 
 extern bool hotplug_mode;
+extern int hotplug_time;
 extern struct list_head scan_devices;
 extern int nDevs;
 extern int opt_n_threads;