Browse Source

Restore devstatus refactoring and moving details to device code

d7372d1 API: Refactor device status into a single common function
74b9378 API: Move device-specific information fetching to the device API model with a new get_extra_device_info function
f4e9426 API: Refactor devstatus method to make it simpler
Luke Dashjr 13 years ago
parent
commit
4003ef7a5f
8 changed files with 146 additions and 254 deletions
  1. 98 215
      api.c
  2. 1 0
      driver-cpu.c
  3. 1 2
      driver-icarus.c
  4. 8 8
      driver-modminer.c
  5. 21 19
      driver-opencl.c
  6. 6 6
      driver-ztex.c
  7. 4 0
      miner.c
  8. 7 4
      miner.h

+ 98 - 215
api.c

@@ -684,7 +684,11 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu
 	api_data->data_was_malloc = copy_data;
 	api_data->data_was_malloc = copy_data;
 
 
 	if (!copy_data)
 	if (!copy_data)
+	{
 		api_data->data = data;
 		api_data->data = data;
+		if (type == API_JSON)
+			json_incref((json_t *)data);
+	}
 	else
 	else
 		switch(type) {
 		switch(type) {
 		case API_ESCAPE:
 		case API_ESCAPE:
@@ -736,6 +740,10 @@ static struct api_data *api_add_data_full(struct api_data *root, char *name, enu
 			api_data->data = (void *)malloc(sizeof(float));
 			api_data->data = (void *)malloc(sizeof(float));
 			*((float *)(api_data->data)) = *((float *)data);
 			*((float *)(api_data->data)) = *((float *)data);
 			break;
 			break;
+		case API_JSON:
+			api_data->data_was_malloc = false;
+			api_data->data = (void *)json_deep_copy((json_t *)data);
+			break;
 		default:
 		default:
 			applog(LOG_ERR, "API: unknown1 data type %d ignored", type);
 			applog(LOG_ERR, "API: unknown1 data type %d ignored", type);
 			api_data->type = API_STRING;
 			api_data->type = API_STRING;
@@ -752,7 +760,7 @@ struct api_data *api_add_escape(struct api_data *root, char *name, char *data, b
 	return api_add_data_full(root, name, API_ESCAPE, (void *)data, copy_data);
 	return api_add_data_full(root, name, API_ESCAPE, (void *)data, copy_data);
 }
 }
 
 
-struct api_data *api_add_string(struct api_data *root, char *name, char *data, bool copy_data)
+struct api_data *api_add_string(struct api_data *root, char *name, const char *data, bool copy_data)
 {
 {
 	return api_add_data_full(root, name, API_STRING, (void *)data, copy_data);
 	return api_add_data_full(root, name, API_STRING, (void *)data, copy_data);
 }
 }
@@ -842,6 +850,11 @@ struct api_data *api_add_hs(struct api_data *root, char *name, double *data, boo
 	return api_add_data_full(root, name, API_HS, (void *)data, copy_data);
 	return api_add_data_full(root, name, API_HS, (void *)data, copy_data);
 }
 }
 
 
+struct api_data *api_add_json(struct api_data *root, char *name, json_t *data, bool copy_data)
+{
+	return api_add_data_full(root, name, API_JSON, (void *)data, copy_data);
+}
+
 static struct api_data *print_data(struct api_data *root, char *buf, bool isjson)
 static struct api_data *print_data(struct api_data *root, char *buf, bool isjson)
 {
 {
 	struct api_data *tmp;
 	struct api_data *tmp;
@@ -924,6 +937,11 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 		case API_TEMP:
 		case API_TEMP:
 			sprintf(buf, "%.2f", *((float *)(root->data)));
 			sprintf(buf, "%.2f", *((float *)(root->data)));
 			break;
 			break;
+		case API_JSON:
+			escape = json_dumps((json_t *)(root->data), JSON_COMPACT);
+			strcpy(buf, escape);
+			free(escape);
+			break;
 		default:
 		default:
 			applog(LOG_ERR, "API: unknown2 data type %d ignored", root->type);
 			applog(LOG_ERR, "API: unknown2 data type %d ignored", root->type);
 			sprintf(buf, "%s%s%s", quote, UNKNOWN, quote);
 			sprintf(buf, "%s%s%s", quote, UNKNOWN, quote);
@@ -932,6 +950,8 @@ static struct api_data *print_data(struct api_data *root, char *buf, bool isjson
 
 
 		buf = strchr(buf, '\0');
 		buf = strchr(buf, '\0');
 
 
+		if (root->type == API_JSON)
+			json_decref((json_t *)root->data);
 		if (root->data_was_malloc)
 		if (root->data_was_malloc)
 			free(root->data);
 			free(root->data);
 
 
@@ -1224,216 +1244,106 @@ static void minerconfig(__maybe_unused SOCKETTYPE c, __maybe_unused char *param,
 		strcat(buf, JSON_CLOSE);
 		strcat(buf, JSON_CLOSE);
 	strcat(io_buffer, buf);
 	strcat(io_buffer, buf);
 }
 }
-#ifdef HAVE_OPENCL
-static void gpustatus(int gpu, bool isjson)
+
+static const char*
+bool2str(bool b)
 {
 {
-	struct api_data *root = NULL;
-	char intensity[20];
-	char buf[TMPBUFSIZ];
-	char *enabled;
-	char *status;
-	float gt, gv;
-	int ga, gf, gp, gc, gm, pt;
+	return b ? YES : NO;
+}
 
 
-	if (gpu >= 0 && gpu < nDevs) {
-		struct cgpu_info *cgpu = &gpus[gpu];
+static const char*
+status2str(enum alive status)
+{
+	switch (status) {
+	case LIFE_WELL:
+		return ALIVE;
+	case LIFE_SICK:
+		return SICK;
+	case LIFE_DEAD:
+		return DEAD;
+	case LIFE_NOSTART:
+		return NOSTART;
+	default:
+		return UNKNOWN;
+	}
+}
 
 
-		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
+static void devstatus_an(struct cgpu_info *cgpu, bool isjson)
+{
+	struct api_data *root = NULL;
+	char buf[TMPBUFSIZ];
+	int n = 0, i;
 
 
-#ifdef HAVE_ADL
-		if (!gpu_stats(gpu, &gt, &gc, &gm, &gv, &ga, &gf, &gp, &pt))
-#endif
-			gt = gv = gm = gc = ga = gf = gp = pt = 0;
+	cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
 
 
-		if (cgpu->deven != DEV_DISABLED)
-			enabled = (char *)YES;
-		else
-			enabled = (char *)NO;
-
-		if (cgpu->status == LIFE_DEAD)
-			status = (char *)DEAD;
-		else if (cgpu->status == LIFE_SICK)
-			status = (char *)SICK;
-		else if (cgpu->status == LIFE_NOSTART)
-			status = (char *)NOSTART;
-		else
-			status = (char *)ALIVE;
+	for (i = 0; i < total_devices; ++i) {
+		if (devices[i] == cgpu)
+			break;
+		if (cgpu->devtype == devices[i]->devtype)
+			++n;
+	}
 
 
-		if (cgpu->dynamic)
-			strcpy(intensity, DYNAMIC);
-		else
-			sprintf(intensity, "%d", cgpu->intensity);
+	root = api_add_int(root, (char*)cgpu->devtype, &n, true);
+	root = api_add_string(root, "Name", cgpu->api->name, false);
+	root = api_add_int(root, "ID", &(cgpu->device_id), false);
+	root = api_add_string(root, "Enabled", bool2str(cgpu->deven != DEV_DISABLED), false);
+	root = api_add_string(root, "Status", status2str(cgpu->status), false);
+	if (cgpu->temp)
+		root = api_add_temp(root, "Temperature", &cgpu->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);
+
+	if (cgpu->api->get_api_extra_device_status)
+		root = api_add_extra(root, cgpu->api->get_api_extra_device_status(cgpu));
 
 
-		root = api_add_int(root, "GPU", &gpu, false);
-		root = api_add_string(root, "Enabled", enabled, false);
-		root = api_add_string(root, "Status", status, false);
-		root = api_add_temp(root, "Temperature", &gt, false);
-		root = api_add_int(root, "Fan Speed", &gf, false);
-		root = api_add_int(root, "Fan Percent", &gp, false);
-		root = api_add_int(root, "GPU Clock", &gc, false);
-		root = api_add_int(root, "Memory Clock", &gm, false);
-		root = api_add_volts(root, "GPU Voltage", &gv, false);
-		root = api_add_int(root, "GPU Activity", &ga, false);
-		root = api_add_int(root, "Powertune", &pt, 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);
-		root = api_add_string(root, "Intensity", intensity, 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 = print_data(root, buf, isjson);
+	strcat(io_buffer, buf);
+}
 
 
-		root = print_data(root, buf, isjson);
-		strcat(io_buffer, buf);
-	}
+#ifdef HAVE_OPENCL
+static void gpustatus(int gpu, bool isjson)
+{
+        if (gpu < 0 || gpu >= nDevs)
+                return;
+        devstatus_an(&gpus[gpu], isjson);
 }
 }
 #endif
 #endif
 #ifdef HAVE_AN_FPGA
 #ifdef HAVE_AN_FPGA
 static void pgastatus(int pga, bool isjson)
 static void pgastatus(int pga, bool isjson)
 {
 {
-	struct api_data *root = NULL;
-	char buf[TMPBUFSIZ];
-	char *enabled;
-	char *status;
-	int numpga = numpgas();
-
-	if (numpga > 0 && pga >= 0 && pga < numpga) {
-		int dev = pgadevice(pga);
-		if (dev < 0) // Should never happen
-			return;
-
-		struct cgpu_info *cgpu = devices[dev];
-		double frequency = 0;
-		float temp = cgpu->temp;
-
-#ifdef USE_ZTEX
-		if (cgpu->api == &ztex_api && cgpu->device_ztex)
-			frequency = cgpu->device_ztex->freqM1 * (cgpu->device_ztex->freqM + 1);
-#endif
-#ifdef USE_MODMINER
-// TODO: a modminer has up to 4 devices but only 1 set of data for all ...
-// except 4 sets of data for temp/clock
-// So this should change in the future to just find the single temp/clock
-// if the modminer code splits the device into seperate devices later
-// For now, just display the highest temp and the average clock
-		if (cgpu->api == &modminer_api) {
-			int tc = cgpu->threads;
-			int i;
-
-			temp = 0;
-			if (tc > 4)
-				tc = 4;
-			for (i = 0; i < tc; i++) {
-				struct thr_info *thr = cgpu->thr[i];
-				struct modminer_fpga_state *state = thr->cgpu_data;
-				if (state->temp > temp)
-					temp = state->temp;
-				frequency += state->clock;
-			}
-			frequency /= (tc ? tc : 1);
-		}
-#endif
-
-		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
-
-		if (cgpu->deven != DEV_DISABLED)
-			enabled = (char *)YES;
-		else
-			enabled = (char *)NO;
-
-		if (cgpu->status == LIFE_DEAD)
-			status = (char *)DEAD;
-		else if (cgpu->status == LIFE_SICK)
-			status = (char *)SICK;
-		else if (cgpu->status == LIFE_NOSTART)
-			status = (char *)NOSTART;
-		else
-			status = (char *)ALIVE;
-
-		root = api_add_int(root, "PGA", &pga, false);
-		root = api_add_string(root, "Name", cgpu->api->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_freq(root, "Frequency", &frequency, false);
-
-		root = print_data(root, buf, isjson);
-		strcat(io_buffer, buf);
-	}
+        int dev = pgadevice(pga);
+        if (dev < 0) // Should never happen
+                return;
+        devstatus_an(devices[dev], isjson);
 }
 }
 #endif
 #endif
 
 
 #ifdef WANT_CPUMINE
 #ifdef WANT_CPUMINE
 static void cpustatus(int cpu, bool isjson)
 static void cpustatus(int cpu, bool isjson)
 {
 {
-	struct api_data *root = NULL;
-	char buf[TMPBUFSIZ];
-
-	if (opt_n_threads > 0 && cpu >= 0 && cpu < num_processors) {
-		struct cgpu_info *cgpu = &cpus[cpu];
-
-		cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
-
-		root = api_add_int(root, "CPU", &cpu, 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_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 = print_data(root, buf, isjson);
-		strcat(io_buffer, buf);
-	}
+        if (opt_n_threads <= 0 || cpu < 0 || cpu >= num_processors)
+                return;
+        devstatus_an(&cpus[cpu], isjson);
 }
 }
 #endif
 #endif
 
 
 static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group)
 {
 {
-	int devcount = 0;
-	int numgpu = 0;
-	int numpga = 0;
 	int i;
 	int i;
 
 
-#ifdef HAVE_OPENCL
-	numgpu = nDevs;
-#endif
-
-#ifdef HAVE_AN_FPGA
-	numpga = numpgas();
-#endif
-
-	if (numgpu == 0 && opt_n_threads == 0 && numpga == 0) {
+	if (total_devices == 0) {
 		strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
 		strcpy(io_buffer, message(MSG_NODEVS, 0, NULL, isjson));
 		return;
 		return;
 	}
 	}
@@ -1445,39 +1355,12 @@ static void devstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, b
 		strcat(io_buffer, JSON_DEVS);
 		strcat(io_buffer, JSON_DEVS);
 	}
 	}
 
 
-#ifdef HAVE_OPENCL
-	for (i = 0; i < nDevs; i++) {
-		if (isjson && devcount > 0)
+	for (i = 0; i < total_devices; ++i) {
+		if (isjson && i > 0)
 			strcat(io_buffer, COMMA);
 			strcat(io_buffer, COMMA);
 
 
-		gpustatus(i, isjson);
-
-		devcount++;
+		devstatus_an(devices[i], isjson);
 	}
 	}
-#endif
-#ifdef HAVE_AN_FPGA
-	if (numpga > 0)
-		for (i = 0; i < numpga; i++) {
-			if (isjson && devcount > 0)
-				strcat(io_buffer, COMMA);
-
-			pgastatus(i, isjson);
-
-			devcount++;
-		}
-#endif
-
-#ifdef WANT_CPUMINE
-	if (opt_n_threads > 0)
-		for (i = 0; i < num_processors; i++) {
-			if (isjson && devcount > 0)
-				strcat(io_buffer, COMMA);
-
-			cpustatus(i, isjson);
-
-			devcount++;
-		}
-#endif
 
 
 	if (isjson)
 	if (isjson)
 		strcat(io_buffer, JSON_CLOSE);
 		strcat(io_buffer, JSON_CLOSE);

+ 1 - 0
driver-cpu.c

@@ -743,6 +743,7 @@ static void cpu_detect()
 
 
 		cgpu = &cpus[i];
 		cgpu = &cpus[i];
 		cgpu->api = &cpu_api;
 		cgpu->api = &cpu_api;
+		cgpu->devtype = "CPU";
 		cgpu->deven = DEV_ENABLED;
 		cgpu->deven = DEV_ENABLED;
 		cgpu->threads = 1;
 		cgpu->threads = 1;
 		cgpu->kname = algo_names[opt_algo];
 		cgpu->kname = algo_names[opt_algo];

+ 1 - 2
driver-icarus.c

@@ -782,7 +782,6 @@ static struct api_data *icarus_api_stats(struct cgpu_info *cgpu)
 {
 {
 	struct api_data *root = NULL;
 	struct api_data *root = NULL;
 	struct ICARUS_INFO *info = icarus_info[cgpu->device_id];
 	struct ICARUS_INFO *info = icarus_info[cgpu->device_id];
-	json_t *ji = json_object();
 
 
 	// Warning, access to these is not locked - but we don't really
 	// Warning, access to these is not locked - but we don't really
 	// care since hashing performance is way more important than
 	// care since hashing performance is way more important than
@@ -828,7 +827,7 @@ struct device_api icarus_api = {
 	.dname = "icarus",
 	.dname = "icarus",
 	.name = "ICA",
 	.name = "ICA",
 	.api_detect = icarus_detect,
 	.api_detect = icarus_detect,
-	.get_extra_device_perf_stats = icarus_perf_stats,
+	.get_api_stats = icarus_api_stats,
 	.thread_prepare = icarus_prepare,
 	.thread_prepare = icarus_prepare,
 	.scanhash = icarus_scanhash,
 	.scanhash = icarus_scanhash,
 	.thread_shutdown = icarus_shutdown,
 	.thread_shutdown = icarus_shutdown,

+ 8 - 8
driver-modminer.c

@@ -372,11 +372,11 @@ get_modminer_statline_before(char *buf, struct cgpu_info *modminer)
 		strcat(buf, "               | ");
 		strcat(buf, "               | ");
 }
 }
 
 
-static json_t*
-get_modminer_extra_device_status(struct cgpu_info*modminer)
+static struct api_data*
+get_modminer_api_extra_device_status(struct cgpu_info*modminer)
 {
 {
-	json_t *info = json_object();
-	char k[7] = "BoardN";
+	struct api_data*root = NULL;
+	static char *k[4] = {"Board0", "Board1", "Board2", "Board3"};
 	int i;
 	int i;
 
 
 	for (i = modminer->threads - 1; i >= 0; --i) {
 	for (i = modminer->threads - 1; i >= 0; --i) {
@@ -387,11 +387,11 @@ get_modminer_extra_device_status(struct cgpu_info*modminer)
 		json_object_set(o, "Temperature", json_integer(state->temp));
 		json_object_set(o, "Temperature", json_integer(state->temp));
 		json_object_set(o, "Frequency", json_real((double)state->clock * 1000000.));
 		json_object_set(o, "Frequency", json_real((double)state->clock * 1000000.));
 
 
-		k[5] = 0x30 + i;
-		json_object_set(info, k, o);
+		root = api_add_json(root, k[i], o, false);
+		json_decref(o);
 	}
 	}
 
 
-	return info;
+	return root;
 }
 }
 
 
 static bool
 static bool
@@ -558,7 +558,7 @@ struct device_api modminer_api = {
 	.name = "MMQ",
 	.name = "MMQ",
 	.api_detect = modminer_detect,
 	.api_detect = modminer_detect,
 	.get_statline_before = get_modminer_statline_before,
 	.get_statline_before = get_modminer_statline_before,
-	.get_extra_device_status = get_modminer_extra_device_status,
+	.get_api_extra_device_status = get_modminer_api_extra_device_status,
 	.thread_prepare = modminer_fpga_prepare,
 	.thread_prepare = modminer_fpga_prepare,
 	.thread_init = modminer_fpga_init,
 	.thread_init = modminer_fpga_init,
 	.scanhash = modminer_scanhash,
 	.scanhash = modminer_scanhash,

+ 21 - 19
driver-opencl.c

@@ -1356,6 +1356,7 @@ static void opencl_detect()
 		struct cgpu_info *cgpu;
 		struct cgpu_info *cgpu;
 
 
 		cgpu = &gpus[i];
 		cgpu = &gpus[i];
+		cgpu->devtype = "GPU";
 		cgpu->deven = DEV_ENABLED;
 		cgpu->deven = DEV_ENABLED;
 		cgpu->api = &opencl_api;
 		cgpu->api = &opencl_api;
 		cgpu->device_id = i;
 		cgpu->device_id = i;
@@ -1402,10 +1403,10 @@ static void get_opencl_statline(char *buf, struct cgpu_info *gpu)
 	tailsprintf(buf, " I:%2d", gpu->intensity);
 	tailsprintf(buf, " I:%2d", gpu->intensity);
 }
 }
 
 
-static json_t*
-get_opencl_extra_device_status(struct cgpu_info *gpu)
+static struct api_data*
+get_opencl_api_extra_device_status(struct cgpu_info *gpu)
 {
 {
-	json_t *info = json_object();
+	struct api_data*root = NULL;
 
 
 	float gt, gv;
 	float gt, gv;
 	int ga, gf, gp, gc, gm, pt;
 	int ga, gf, gp, gc, gm, pt;
@@ -1413,21 +1414,22 @@ get_opencl_extra_device_status(struct cgpu_info *gpu)
 	if (!gpu_stats(gpu->device_id, &gt, &gc, &gm, &gv, &ga, &gf, &gp, &pt))
 	if (!gpu_stats(gpu->device_id, &gt, &gc, &gm, &gv, &ga, &gf, &gp, &pt))
 #endif
 #endif
 		gt = gv = gm = gc = ga = gf = gp = pt = 0;
 		gt = gv = gm = gc = ga = gf = gp = pt = 0;
-	json_object_set(info, "Fan Speed", json_integer(gf));
-	json_object_set(info, "Fan Percent", json_integer(gp));
-	json_object_set(info, "GPU Clock", json_integer(gc));
-	json_object_set(info, "Memory Clock", json_integer(gm));
-	json_object_set(info, "GPU Voltage", json_real(gv));
-	json_object_set(info, "GPU Activity", json_integer(ga));
-	json_object_set(info, "Powertune", json_integer(pt));
-
-	json_object_set(info, "Intensity",
-					gpu->dynamic
-						? json_string("D")
-						: json_integer(gpu->intensity)
-	);
-
-	return info;
+	root = api_add_int(root, "Fan Speed", &gf, true);
+	root = api_add_int(root, "Fan Percent", &gp, true);
+	root = api_add_int(root, "GPU Clock", &gc, true);
+	root = api_add_int(root, "Memory Clock", &gm, true);
+	root = api_add_volts(root, "GPU Voltage", &gv, true);
+	root = api_add_int(root, "GPU Activity", &ga, true);
+	root = api_add_int(root, "Powertune", &pt, true);
+
+	char intensity[20];
+	if (gpu->dynamic)
+		strcpy(intensity, "D");
+	else
+		sprintf(intensity, "%d", gpu->intensity);
+	root = api_add_string(root, "Intensity", intensity, true);
+
+	return root;
 }
 }
 
 
 struct opencl_thread_data {
 struct opencl_thread_data {
@@ -1711,7 +1713,7 @@ struct device_api opencl_api = {
 	.get_statline_before = get_opencl_statline_before,
 	.get_statline_before = get_opencl_statline_before,
 #endif
 #endif
 	.get_statline = get_opencl_statline,
 	.get_statline = get_opencl_statline,
-	.get_extra_device_status = get_opencl_extra_device_status,
+	.get_api_extra_device_status = get_opencl_api_extra_device_status,
 	.thread_prepare = opencl_thread_prepare,
 	.thread_prepare = opencl_thread_prepare,
 	.thread_init = opencl_thread_init,
 	.thread_init = opencl_thread_init,
 	.free_work = opencl_free_work,
 	.free_work = opencl_free_work,

+ 6 - 6
driver-ztex.c

@@ -351,18 +351,18 @@ static void ztex_statline_before(char *buf, struct cgpu_info *cgpu)
 	}
 	}
 }
 }
 
 
-static json_t*
-get_ztex_extra_device_status(struct cgpu_info *ztex)
+static struct api_data*
+get_ztex_api_extra_device_status(struct cgpu_info *ztex)
 {
 {
-	json_t *info = json_object();
+	struct api_data*root = NULL;
 	struct libztex_device *ztexr = ztex->device_ztex;
 	struct libztex_device *ztexr = ztex->device_ztex;
 
 
 	if (ztexr) {
 	if (ztexr) {
 		double frequency = ztexr->freqM1 * (ztexr->freqM + 1);
 		double frequency = ztexr->freqM1 * (ztexr->freqM + 1);
-		json_object_set(info, "Frequency", json_real(frequency));
+		root = api_add_freq(root, "Frequency", &frequency, true);
 	}
 	}
 
 
-	return info;
+	return root;
 }
 }
 
 
 static bool ztex_prepare(struct thr_info *thr)
 static bool ztex_prepare(struct thr_info *thr)
@@ -408,7 +408,7 @@ struct device_api ztex_api = {
 	.name = "ZTX",
 	.name = "ZTX",
 	.api_detect = ztex_detect,
 	.api_detect = ztex_detect,
 	.get_statline_before = ztex_statline_before,
 	.get_statline_before = ztex_statline_before,
-	.get_extra_device_status = get_ztex_extra_device_status,
+	.get_api_extra_device_status = get_ztex_api_extra_device_status,
 	.thread_prepare = ztex_prepare,
 	.thread_prepare = ztex_prepare,
 	.scanhash = ztex_scanhash,
 	.scanhash = ztex_scanhash,
 	.thread_shutdown = ztex_shutdown,
 	.thread_shutdown = ztex_shutdown,

+ 4 - 0
miner.c

@@ -5285,6 +5285,10 @@ int main(int argc, char *argv[])
 	cpu_api.api_detect();
 	cpu_api.api_detect();
 #endif
 #endif
 
 
+	for (i = 0; i < total_devices; ++i)
+		if (!devices[i]->devtype)
+			devices[i]->devtype = "PGA";
+
 	if (devices_enabled == -1) {
 	if (devices_enabled == -1) {
 		applog(LOG_ERR, "Devices detected:");
 		applog(LOG_ERR, "Devices detected:");
 		for (i = 0; i < total_devices; ++i) {
 		for (i = 0; i < total_devices; ++i) {

+ 7 - 4
miner.h

@@ -231,8 +231,8 @@ struct device_api {
 	void (*reinit_device)(struct cgpu_info*);
 	void (*reinit_device)(struct cgpu_info*);
 	void (*get_statline_before)(char*, struct cgpu_info*);
 	void (*get_statline_before)(char*, struct cgpu_info*);
 	void (*get_statline)(char*, struct cgpu_info*);
 	void (*get_statline)(char*, struct cgpu_info*);
-	json_t* (*get_extra_device_detail)(struct cgpu_info*);
-	json_t* (*get_extra_device_status)(struct cgpu_info*);
+	struct api_data* (*get_api_extra_device_detail)(struct cgpu_info*);
+	struct api_data* (*get_api_extra_device_status)(struct cgpu_info*);
 	struct api_data *(*get_api_stats)(struct cgpu_info*);
 	struct api_data *(*get_api_stats)(struct cgpu_info*);
 
 
 	// Thread-specific functions
 	// Thread-specific functions
@@ -303,6 +303,7 @@ struct cgminer_pool_stats {
 struct cgpu_info {
 struct cgpu_info {
 	int cgminer_id;
 	int cgminer_id;
 	const struct device_api *api;
 	const struct device_api *api;
+	const char *devtype;
 	int device_id;
 	int device_id;
 	const char *name;
 	const char *name;
 	const char *device_path;
 	const char *device_path;
@@ -791,7 +792,8 @@ enum api_data_type {
 	API_UTILITY,
 	API_UTILITY,
 	API_FREQ,
 	API_FREQ,
 	API_VOLTS,
 	API_VOLTS,
-	API_HS
+	API_HS,
+	API_JSON,
 };
 };
 
 
 struct api_data {
 struct api_data {
@@ -804,7 +806,7 @@ struct api_data {
 };
 };
 
 
 extern struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data);
 extern struct api_data *api_add_escape(struct api_data *root, char *name, char *data, bool copy_data);
-extern struct api_data *api_add_string(struct api_data *root, char *name, char *data, bool copy_data);
+extern struct api_data *api_add_string(struct api_data *root, char *name, const char *data, bool copy_data);
 extern struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data);
 extern struct api_data *api_add_const(struct api_data *root, char *name, const char *data, bool copy_data);
 extern struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data);
 extern struct api_data *api_add_int(struct api_data *root, char *name, int *data, bool copy_data);
 extern struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data);
 extern struct api_data *api_add_uint(struct api_data *root, char *name, unsigned int *data, bool copy_data);
@@ -822,5 +824,6 @@ extern struct api_data *api_add_utility(struct api_data *root, char *name, doubl
 extern struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data);
 extern struct api_data *api_add_freq(struct api_data *root, char *name, double *data, bool copy_data);
 extern struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data);
 extern struct api_data *api_add_volts(struct api_data *root, char *name, float *data, bool copy_data);
 extern struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data);
 extern struct api_data *api_add_hs(struct api_data *root, char *name, double *data, bool copy_data);
+extern struct api_data *api_add_json(struct api_data *root, char *name, json_t *data, bool copy_data);
 
 
 #endif /* __MINER_H__ */
 #endif /* __MINER_H__ */