Browse Source

Refactor set_device interface to use option arrays

Luke Dashjr 12 years ago
parent
commit
21f5771e47
5 changed files with 132 additions and 28 deletions
  1. 17 13
      api.c
  2. 79 0
      deviceapi.c
  3. 16 0
      deviceapi.h
  4. 19 15
      miner.c
  5. 1 0
      miner.h

+ 17 - 13
api.c

@@ -1157,7 +1157,7 @@ foundit:
 // All replies (except BYE and RESTART) start with a message
 //  thus for JSON, message() inserts JSON_START at the front
 //  and send_result() adds JSON_END at the end
-static void message(struct io_data *io_data, int messageid, int paramid, char *param2, bool isjson)
+static void message(struct io_data * const io_data, int messageid, const int paramid, const char * const param2, const bool isjson)
 {
 	struct api_data *root = NULL;
 	char buf[TMPBUFSIZ];
@@ -3303,7 +3303,6 @@ static void setconfig(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char
 static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
 	struct cgpu_info *cgpu;
-	struct device_drv *drv;
 	char buf[TMPBUFSIZ];
 	int numpga = numpgas();
 
@@ -3338,23 +3337,28 @@ static void pgaset(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe
 	}
 
 	cgpu = get_devices(dev);
-	drv = cgpu->drv;
 
 	char *set = strchr(opt, ',');
 	if (set)
 		*(set++) = '\0';
 
-	if (!drv->set_device)
-		message(io_data, MSG_PGANOSET, id, NULL, isjson);
-	else {
-		char *ret = drv->set_device(cgpu, opt, set, buf);
-		if (ret) {
-			if (strcasecmp(opt, "help") == 0)
-				message(io_data, MSG_PGAHELP, id, ret, isjson);
-			else
-				message(io_data, MSG_PGASETERR, id, ret, isjson);
-		} else
+	enum bfg_set_device_replytype success;
+	const char *ret = proc_set_device(cgpu, opt, set, buf, &success);
+	switch (success)
+	{
+		case SDR_HELP:
+			message(io_data, MSG_PGAHELP, id, ret, isjson);
+			break;
+		case SDR_OK:
 			message(io_data, MSG_PGASETOK, id, NULL, isjson);
+			break;
+		case SDR_UNKNOWN:
+		case SDR_ERR:
+			message(io_data, MSG_PGASETERR, id, ret, isjson);
+			break;
+		case SDR_AUTO:
+		case SDR_NOSUPP:
+			message(io_data, MSG_PGANOSET, id, NULL, isjson);
 	}
 }
 #endif

+ 79 - 0
deviceapi.c

@@ -847,6 +847,85 @@ bool add_cgpu_slave(struct cgpu_info *cgpu, struct cgpu_info *prev_cgpu)
 	return true;
 }
 
+const char *proc_set_device_help(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	const struct bfg_set_device_definition *sdf;
+	char *p = replybuf;
+	bool first = true;
+	
+	*out_success = SDR_HELP;
+	sdf = proc->set_device_funcs;
+	if (!sdf)
+nohelp:
+		return "No help available";
+	
+	for ( ; sdf->optname; ++sdf)
+	{
+		if (!sdf->description)
+			continue;
+		if (first)
+			first = false;
+		else
+			p++[0] = '\n';
+		p += sprintf(p, "%s: %s", sdf->optname, sdf->description);
+	}
+	if (replybuf == p)
+		goto nohelp;
+	return replybuf;
+}
+
+static inline
+void _set_auto_sdr(enum bfg_set_device_replytype * const out_success, const char * const rv, const char * const optname)
+{
+	if (!rv)
+		*out_success = SDR_OK;
+	else
+	if (!strcasecmp(optname, "help"))
+		*out_success = SDR_HELP;
+	else
+		*out_success = SDR_ERR;
+}
+
+const char *_proc_set_device(struct cgpu_info * const proc, const char * const optname, const char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	const struct bfg_set_device_definition *sdf;
+	
+	sdf = proc->set_device_funcs;
+	if (!sdf)
+	{
+		*out_success = SDR_NOSUPP;
+		return "Device does not support setting parameters.";
+	}
+	for ( ; sdf->optname; ++sdf)
+		if (!strcasecmp(optname, sdf->optname))
+		{
+			*out_success = SDR_AUTO;
+			const char * const rv = sdf->func(proc, optname, newvalue, replybuf, out_success);
+			if (SDR_AUTO == *out_success)
+				_set_auto_sdr(out_success, rv, optname);
+			return rv;
+		}
+	
+	if (!strcasecmp(optname, "help"))
+		return proc_set_device_help(proc, optname, newvalue, replybuf, out_success);
+	
+	*out_success = SDR_UNKNOWN;
+	sprintf(replybuf, "Unknown option: %s", optname);
+	return replybuf;
+}
+
+const char *proc_set_device(struct cgpu_info * const proc, char * const optname, char * const newvalue, char * const replybuf, enum bfg_set_device_replytype * const out_success)
+{
+	if (proc->drv->set_device)
+	{
+		const char * const rv = proc->drv->set_device(proc, optname, newvalue, replybuf);
+		_set_auto_sdr(out_success, rv, optname);
+		return rv;
+	}
+	
+	return _proc_set_device(proc, optname, newvalue, replybuf, out_success);
+}
+
 #ifdef NEED_BFG_LOWL_VCOM
 bool _serial_detect_all(struct lowlevel_device_info * const info, void * const userp)
 {

+ 16 - 0
deviceapi.h

@@ -76,6 +76,22 @@ extern void *miner_thread(void *);
 extern void add_cgpu_live(void*);
 extern bool add_cgpu_slave(struct cgpu_info *, struct cgpu_info *master);
 
+enum bfg_set_device_replytype {
+	SDR_AUTO,
+	SDR_OK,
+	SDR_ERR,
+	SDR_HELP,
+	SDR_UNKNOWN,
+	SDR_NOSUPP,
+};
+typedef const char *(*bfg_set_device_func_t)(struct cgpu_info *proc, const char *optname, const char *newvalue, char *replybuf, enum bfg_set_device_replytype *out_success);
+struct bfg_set_device_definition {
+	const char *optname;
+	bfg_set_device_func_t func;
+	const char *description;
+};
+extern const char *proc_set_device(struct cgpu_info *proc, char *optname, char *newvalue, char *replybuf, enum bfg_set_device_replytype *out_success);
+
 typedef bool(*detectone_func_t)(const char*);
 typedef int(*autoscan_func_t)();
 

+ 19 - 15
miner.c

@@ -9753,7 +9753,6 @@ void proc_enable(struct cgpu_info *cgpu)
 
 void cgpu_set_defaults(struct cgpu_info * const cgpu)
 {
-	const struct device_drv * const drv = cgpu->drv;
 	struct string_elist *setstr_elist;
 	const char *p, *p2;
 	char replybuf[0x2000];
@@ -9777,13 +9776,6 @@ void cgpu_set_defaults(struct cgpu_info * const cgpu)
 		applog(LOG_DEBUG, "%"PRIpreprv": %s: Matched with set default: %s",
 		       cgpu->proc_repr, __func__, setstr);
 		
-		if (!drv->set_device)
-		{
-			applog(LOG_WARNING, "%"PRIpreprv": set_device is not implemented (trying to apply rule: %s)",
-			       cgpu->proc_repr, setstr);
-			continue;
-		}
-		
 		if (p[0] == ':')
 			++p;
 		p2 = strchr(p, '=');
@@ -9808,13 +9800,25 @@ void cgpu_set_defaults(struct cgpu_info * const cgpu)
 			memcpy(setval, p2, L);
 		setval[L] = '\0';
 		
-		p = drv->set_device(cgpu, opt, setval, replybuf);
-		if (p)
-			applog(LOG_WARNING, "%"PRIpreprv": Applying rule %s: %s",
-			       cgpu->proc_repr, setstr, p);
-		else
-			applog(LOG_DEBUG, "%"PRIpreprv": Applied rule %s",
-			       cgpu->proc_repr, setstr);
+		enum bfg_set_device_replytype success;
+		p = proc_set_device(cgpu, opt, setval, replybuf, &success);
+		switch (success)
+		{
+			case SDR_OK:
+				applog(LOG_DEBUG, "%"PRIpreprv": Applied rule %s",
+				       cgpu->proc_repr, setstr);
+				break;
+			case SDR_ERR:
+			case SDR_HELP:
+			case SDR_UNKNOWN:
+				applog(LOG_WARNING, "%"PRIpreprv": Applying rule %s: %s",
+				       cgpu->proc_repr, setstr, p);
+				break;
+			case SDR_AUTO:
+			case SDR_NOSUPP:
+				applog(LOG_WARNING, "%"PRIpreprv": set_device is not implemented (trying to apply rule: %s)",
+				       cgpu->proc_repr, setstr);
+		}
 	}
 	cgpu->already_set_defaults = true;
 }

+ 1 - 0
miner.h

@@ -446,6 +446,7 @@ struct cgpu_info {
 	int cgminer_id;
 	int device_line_id;
 	struct device_drv *drv;
+	const struct bfg_set_device_definition *set_device_funcs;
 	const char *devtype;
 	int device_id;
 	char *dev_repr;