From a73ed9665a846f6824e94b34b0f548280d0e2c2a Mon Sep 17 00:00:00 2001 From: Kano Date: Sat, 22 Jun 2013 21:17:23 +1000 Subject: [PATCH] API V1.26 update ASIC support --- API-README | 66 ++++++++++--- api.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 319 insertions(+), 18 deletions(-) diff --git a/API-README b/API-README index a05e8a71..29964b02 100644 --- a/API-README +++ b/API-README @@ -60,7 +60,7 @@ response, otherwise it replies with text formatted as described further below. The JSON request format required is '{"command":"CMD","parameter":"PARAM"}' (though of course parameter is not required for all requests) where "CMD" is from the "Request" column below and "PARAM" would be e.g. -the CPU/GPU number if required. +the ASC/GPU number if required. An example request in both formats to set GPU 0 fan to 80%: gpufan|0,80 @@ -115,8 +115,8 @@ The list of requests - a (*) means it requires privileged access - and replies a config CONFIG Some miner configuration information: GPU Count=N, <- the number of GPUs + ASC Count=N, <- the number of ASCs PGA Count=N, <- the number of PGAs - CPU Count=N, <- the number of CPUs Pool Count=N, <- the number of Pools ADL=X, <- Y or N if ADL is compiled in the code ADL in use=X, <- Y or N if any GPU has ADL @@ -135,7 +135,7 @@ The list of requests - a (*) means it requires privileged access - and replies a pools POOLS The status of each pool e.g. Pool=0,URL=http://pool.com:6311,Status=Alive,...| - devs DEVS Each available GPU, PGA and CPU with their details + devs DEVS Each available GPU, PGA and ASC with their details e.g. GPU=0,Accepted=NN,MHS av=NNN,...,Intensity=D| Last Share Time=NNN, <- standand long time in seconds (or 0 if none) of last accepted share @@ -143,7 +143,7 @@ The list of requests - a (*) means it requires privileged access - and replies a Last Valid Work=NNN, <- standand long time in seconds of last work returned that wasn't an HW: Will not report PGAs if PGA mining is disabled - Will not report CPUs if CPU mining is disabled + Will not report ASCs if ASC mining is disabled gpu|N GPU The details of a single GPU number N in the same format and details as for DEVS @@ -153,19 +153,11 @@ The list of requests - a (*) means it requires privileged access - and replies a This is only available if PGA mining is enabled Use 'pgacount' or 'config' first to see if there are any - cpu|N CPU The details of a single CPU number N in the same - format and details as for DEVS - This is only available if CPU mining is enabled - Use 'cpucount' or 'config' first to see if there are any - gpucount GPUS Count=N| <- the number of GPUs pgacount PGAS Count=N| <- the number of PGAs Always returns 0 if PGA mining is disabled - cpucount CPUS Count=N| <- the number of CPUs - Always returns 0 if CPU mining is disabled - switchpool|N (*) none There is no reply section just the STATUS section stating the results of switching pool N to the @@ -370,8 +362,39 @@ The list of requests - a (*) means it requires privileged access - and replies a 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 + asc|N ASC The details of a single ASC number N in the same + format and details as for DEVS + This is only available if ASC mining is enabled + Use 'asccount' or 'config' first to see if there + are any + + ascenable|N (*) + none There is no reply section just the STATUS section + stating the results of the enable request + You cannot enable a ASC if it's status is not WELL + This is only available if ASC mining is enabled + + ascdisable|N (*) + none There is no reply section just the STATUS section + stating the results of the disable request + This is only available if ASC mining is enabled + + ascidentify|N (*) + none There is no reply section just the STATUS section + stating the results of the identify request + This is only available if ASC mining is enabled + and currently only BFL ASICs support this command + On a BFL single it will flash the led on the front + of the device for appoximately 4s + All other non BFL ASIC devices will return a + warning status message stating that they dont + support it + + asccount ASCS Count=N| <- the number of ASCs + Always returns 0 if ASC mining is disabled + +When you enable, disable or restart a GPU, PGA or ASC, you will also get +Thread messages in the cgminer status window The 'poolpriority' command can be used to reset the priority order of multiple pools with a single command - 'switchpool' only sets a single pool to first priority @@ -423,6 +446,21 @@ miner.php - an example web page to access the API Feature Changelog for external applications using the API: +API V1.26 (cgminer v3.2.3) + +Remove all CPU support (cgminer v3.0.0) + +Added API commands: + 'asc' + 'ascenable' + 'ascdisable' + 'ascidentify|N' (only works for BFL ASICs so far) + 'asccount' + +Various additions to the debug 'stats' command + +---------- + API V1.25 Added API commands: diff --git a/api.c b/api.c index 6aebd93b..88f0f219 100644 --- a/api.c +++ b/api.c @@ -134,7 +134,7 @@ static const char SEPARATOR = '|'; #define SEPSTR "|" static const char GPUSEP = ','; -static const char *APIVERSION = "1.25"; +static const char *APIVERSION = "1.26"; static const char *DEAD = "Dead"; #if defined(HAVE_OPENCL) || defined(HAVE_AN_FPGA) || defined(HAVE_AN_ASIC) static const char *SICK = "Sick"; @@ -219,8 +219,13 @@ static const char *OSINFO = #define _PGA "PGA" #endif +#ifdef HAVE_AN_ASIC +#define _ASC "ASC" +#endif + #define _GPUS "GPUS" #define _PGAS "PGAS" +#define _ASCS "ASCS" #define _NOTIFY "NOTIFY" #define _DEVDETAILS "DEVDETAILS" #define _BYE "BYE" @@ -255,8 +260,13 @@ static const char ISJSON = '{'; #define JSON_PGA JSON1 _PGA JSON2 #endif +#ifdef HAVE_AN_ASIC +#define JSON_ASC JSON1 _ASC JSON2 +#endif + #define JSON_GPUS JSON1 _GPUS JSON2 #define JSON_PGAS JSON1 _PGAS JSON2 +#define JSON_ASCS JSON1 _ASCS JSON2 #define JSON_NOTIFY JSON1 _NOTIFY JSON2 #define JSON_DEVDETAILS JSON1 _DEVDETAILS JSON2 #define JSON_BYE JSON1 _BYE JSON1 @@ -381,13 +391,28 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_ZERINV 95 #define MSG_ZERSUM 96 #define MSG_ZERNOSUM 97 -#define MSG_USBNODEV 98 +#define MSG_PGAUSBNODEV 98 #define MSG_INVHPLG 99 #define MSG_HOTPLUG 100 #define MSG_DISHPLG 101 #define MSG_NOHPLG 102 #define MSG_MISHPLG 103 +#define MSG_NUMASC 104 +#ifdef HAVE_AN_ASIC +#define MSG_ASCNON 105 +#define MSG_ASCDEV 106 +#define MSG_INVASC 107 +#define MSG_ASCLRENA 108 +#define MSG_ASCLRDIS 109 +#define MSG_ASCENA 110 +#define MSG_ASCDIS 111 +#define MSG_ASCUNW 112 +#define MSG_ASCIDENT 113 +#define MSG_ASCNOID 114 +#define MSG_ASCUSBNODEV 115 +#endif + enum code_severity { SEVERITY_ERR, SEVERITY_WARN, @@ -399,9 +424,11 @@ enum code_severity { enum code_parameters { PARAM_GPU, PARAM_PGA, + PARAM_ASC, PARAM_PID, PARAM_GPUMAX, PARAM_PGAMAX, + PARAM_ASCMAX, PARAM_PMAX, PARAM_POOLMAX, @@ -487,6 +514,7 @@ struct CODES { #endif { SEVERITY_SUCC, MSG_NUMGPU, PARAM_NONE, "GPU count" }, { SEVERITY_SUCC, MSG_NUMPGA, PARAM_NONE, "PGA count" }, + { SEVERITY_SUCC, MSG_NUMASC, PARAM_NONE, "ASC count" }, { SEVERITY_SUCC, MSG_VERSION, PARAM_NONE, "CGMiner versions" }, { SEVERITY_ERR, MSG_INVJSON, PARAM_NONE, "Invalid JSON" }, { SEVERITY_ERR, MSG_MISCMD, PARAM_CMD, "Missing JSON '%s'" }, @@ -561,13 +589,26 @@ struct CODES { { SEVERITY_SUCC, MSG_ZERSUM, PARAM_STR, "Zeroed %s stats with summary" }, { SEVERITY_SUCC, MSG_ZERNOSUM, PARAM_STR, "Zeroed %s stats without summary" }, #ifdef USE_USBUTILS - { SEVERITY_ERR, MSG_USBNODEV, PARAM_PGA, "PGA%d has no device" }, + { SEVERITY_ERR, MSG_PGAUSBNODEV, PARAM_PGA, "PGA%d has no device" }, + { SEVERITY_ERR, MSG_ASCUSBNODEV, PARAM_PGA, "ASC%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" }, +#ifdef HAVE_AN_ASIC + { SEVERITY_ERR, MSG_ASCNON, PARAM_NONE, "No ASCs" }, + { SEVERITY_SUCC, MSG_ASCDEV, PARAM_ASC, "ASC%d" }, + { SEVERITY_ERR, MSG_INVASC, PARAM_ASCMAX, "Invalid ASC id %d - range is 0 - %d" }, + { SEVERITY_INFO, MSG_ASCLRENA,PARAM_ASC, "ASC %d already enabled" }, + { SEVERITY_INFO, MSG_ASCLRDIS,PARAM_ASC, "ASC %d already disabled" }, + { SEVERITY_INFO, MSG_ASCENA, PARAM_ASC, "ASC %d sent enable message" }, + { SEVERITY_INFO, MSG_ASCDIS, PARAM_ASC, "ASC %d set disable flag" }, + { SEVERITY_ERR, MSG_ASCUNW, PARAM_ASC, "ASC %d is not flagged WELL, cannot enable" }, + { SEVERITY_SUCC, MSG_ASCIDENT,PARAM_ASC, "Identify command sent to ASC%d" }, + { SEVERITY_WARN, MSG_ASCNOID, PARAM_ASC, "ASC%d does not support identify" }, +#endif { SEVERITY_FAIL, 0, 0, NULL } }; @@ -1296,6 +1337,7 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p switch(codes[i].params) { case PARAM_GPU: case PARAM_PGA: + case PARAM_ASC: case PARAM_PID: case PARAM_INT: sprintf(buf, codes[i].description, paramid); @@ -1313,6 +1355,12 @@ static void message(struct io_data *io_data, int messageid, int paramid, char *p pga = numpgas(); sprintf(buf, codes[i].description, paramid, pga - 1); break; +#endif +#ifdef HAVE_AN_ASIC + case PARAM_ASCMAX: + asc = numascs(); + sprintf(buf, codes[i].description, paramid, asc - 1); + break; #endif case PARAM_PMAX: sprintf(buf, codes[i].description, total_pools); @@ -1901,7 +1949,7 @@ static void pgaenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char #ifdef USE_USBUTILS if (cgpu->usbinfo.nodev) { - message(io_data, MSG_USBNODEV, id, NULL, isjson); + message(io_data, MSG_PGAUSBNODEV, id, NULL, isjson); return; } #endif @@ -3386,6 +3434,214 @@ static void dohotplug(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __ma #endif } +#ifdef HAVE_AN_ASIC +static void ascdev(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + bool io_open = false; + int numasc = numascs(); + int id; + + if (numasc == 0) { + message(io_data, MSG_ASCNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= numasc) { + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + message(io_data, MSG_ASCDEV, id, NULL, isjson); + + if (isjson) + io_open = io_add(io_data, COMSTR JSON_ASC); + + ascstatus(io_data, id, isjson, false); + + if (isjson && io_open) + io_close(io_data); +} + +static void ascenable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu; + int numasc = numascs(); + struct thr_info *thr; + int asc; + int id; + int i; + + if (numasc == 0) { + message(io_data, MSG_ASCNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= numasc) { + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + int dev = ascdevice(id); + if (dev < 0) { // Should never happen + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + cgpu = get_devices(dev); + + applog(LOG_DEBUG, "API: request to ascenable ascid %d device %d %s%u", + id, dev, cgpu->drv->name, cgpu->device_id); + + if (cgpu->deven != DEV_DISABLED) { + message(io_data, MSG_ASCLRENA, id, NULL, isjson); + return; + } + +#if 0 /* A DISABLED device wont change status FIXME: should disabling make it WELL? */ + if (cgpu->status != LIFE_WELL) { + message(io_data, MSG_ASCUNW, id, NULL, isjson); + return; + } +#endif + +#ifdef USE_USBUTILS + if (cgpu->usbinfo.nodev) { + message(io_data, MSG_ASCUSBNODEV, id, NULL, isjson); + return; + } +#endif + + for (i = 0; i < mining_threads; i++) { + thr = get_thread(i); + asc = thr->cgpu->cgminer_id; + if (asc == dev) { + cgpu->deven = DEV_ENABLED; + applog(LOG_DEBUG, "API: Pushing sem post to thread %d", thr->id); + cgsem_post(&thr->sem); + } + } + + message(io_data, MSG_ASCENA, id, NULL, isjson); +} + +static void ascdisable(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu; + int numasc = numascs(); + int id; + + if (numasc == 0) { + message(io_data, MSG_ASCNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= numasc) { + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + int dev = ascdevice(id); + if (dev < 0) { // Should never happen + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + cgpu = get_devices(dev); + + applog(LOG_DEBUG, "API: request to ascdisable ascid %d device %d %s%u", + id, dev, cgpu->drv->name, cgpu->device_id); + + if (cgpu->deven == DEV_DISABLED) { + message(io_data, MSG_ASCLRDIS, id, NULL, isjson); + return; + } + + cgpu->deven = DEV_DISABLED; + + message(io_data, MSG_ASCDIS, id, NULL, isjson); +} + +static void ascidentify(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + struct cgpu_info *cgpu; + struct device_drv *drv; + int numasc = numascs(); + int id; + + if (numasc == 0) { + message(io_data, MSG_ASCNON, 0, NULL, isjson); + return; + } + + if (param == NULL || *param == '\0') { + message(io_data, MSG_MISID, 0, NULL, isjson); + return; + } + + id = atoi(param); + if (id < 0 || id >= numasc) { + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + int dev = ascdevice(id); + if (dev < 0) { // Should never happen + message(io_data, MSG_INVASC, id, NULL, isjson); + return; + } + + cgpu = get_devices(dev); + drv = cgpu->drv; + + if (!drv->identify_device) + message(io_data, MSG_ASCNOID, id, NULL, isjson); + else { + drv->identify_device(cgpu); + message(io_data, MSG_ASCIDENT, id, NULL, isjson); + } +} +#endif + +static void asccount(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __maybe_unused char *param, bool isjson, __maybe_unused char group) +{ + struct api_data *root = NULL; + char buf[TMPBUFSIZ]; + bool io_open; + int count = 0; + +#ifdef HAVE_AN_ASIC + count = numascs(); +#endif + + message(io_data, MSG_NUMASC, 0, NULL, isjson); + io_open = io_add(io_data, isjson ? COMSTR JSON_ASCS : _ASCS COMSTR); + + root = api_add_int(root, "Count", &count, false); + + root = print_data(root, buf, isjson, false); + io_add(io_data, buf); + if (isjson && io_open) + io_close(io_data); +} + static void checkcommand(struct io_data *io_data, __maybe_unused SOCKETTYPE c, char *param, bool isjson, char group); struct CMDS { @@ -3443,6 +3699,13 @@ struct CMDS { #endif { "zero", dozero, true }, { "hotplug", dohotplug, true }, +#ifdef HAVE_AN_ASIC + { "asc", ascdev, false }, + { "ascenable", ascenable, true }, + { "ascdisable", ascdisable, true }, + { "ascidentify", ascidentify, true }, +#endif + { "asccount", asccount, false }, { NULL, NULL, false } };