From 9487ba05cdbed2f9135ab030e91b2a06cc4cbbfb Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 4 Sep 2012 12:52:11 +1000 Subject: [PATCH] API/BFL identify a device - currently only BFL to flash the led --- API-README | 17 +++++++++++++++ api.c | 45 ++++++++++++++++++++++++++++++++++++++++ driver-bitforce.c | 53 +++++++++++++++++++++++++++++++++++++++++++++-- miner.h | 2 ++ 4 files changed, 115 insertions(+), 2 deletions(-) diff --git a/API-README b/API-README index 4f812c1470..8a686fcd08 100644 --- a/API-README +++ b/API-README @@ -259,6 +259,22 @@ The list of requests - a (*) means it requires privileged access - and replies a stating the results of the disable request This is only available if PGA mining is enabled + pgaidentify|N (*) + none There is no reply section just the STATUS section + stating the results of the identify request + This is only available if PGA mining is enabled + and currently only BFL singles 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 PGA devices will return an error + status message stating that they dont support it + This adds a 4s delay to the BFL share being processed + so you may get a message stating that procssing took + longer than 7000ms if the request was sent towards + the end of the timing of any work being worked on + e.g.: BFL0: took 8438ms - longer than 7000ms + You should ignore this + devdetails DEVDETAILS Each device with a list of their static details This lists all devices including those not supported by the 'devs' command @@ -359,6 +375,7 @@ API V1.19 Added API commands: 'debug' + 'pgaidentify|N' Modified API commands: Change pool field name 'Diff1 Shares' to 'Diff1 Work' diff --git a/api.c b/api.c index a8123810b3..839ea660b5 100644 --- a/api.c +++ b/api.c @@ -393,6 +393,8 @@ static const char *JSON_PARAMETER = "parameter"; #define MSG_FOO 77 #define MSG_MINECOIN 78 #define MSG_DEBUGSET 79 +#define MSG_PGAIDENT 80 +#define MSG_PGANOID 81 enum code_severity { SEVERITY_ERR, @@ -547,6 +549,10 @@ struct CODES { { SEVERITY_SUCC, MSG_FOO, PARAM_BOOL, "Failover-Only set to %s" }, { SEVERITY_SUCC, MSG_MINECOIN,PARAM_NONE, "CGMiner coin" }, { SEVERITY_SUCC, MSG_DEBUGSET,PARAM_STR, "Debug settings" }, +#ifdef HAVE_AN_FPGA + { SEVERITY_SUCC, MSG_PGAIDENT,PARAM_PGA, "Identify command sent to PGA%d" }, + { SEVERITY_ERR, MSG_PGANOID, PARAM_PGA, "PGA%d does not support identify" }, +#endif { SEVERITY_FAIL, 0, 0, NULL } }; @@ -1700,6 +1706,44 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __ strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } + +static void pgaidentify(__maybe_unused SOCKETTYPE c, char *param, bool isjson, __maybe_unused char group) +{ + int numpga = numpgas(); + int id; + + if (numpga == 0) { + strcpy(io_buffer, message(MSG_PGANON, 0, NULL, isjson)); + return; + } + + if (param == NULL || *param == '\0') { + strcpy(io_buffer, message(MSG_MISID, 0, NULL, isjson)); + return; + } + + id = atoi(param); + if (id < 0 || id >= numpga) { + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + int dev = pgadevice(id); + if (dev < 0) { // Should never happen + strcpy(io_buffer, message(MSG_INVPGA, id, NULL, isjson)); + return; + } + + struct cgpu_info *cgpu = devices[dev]; + struct device_api *api = cgpu->api; + + if (!api->identify_device) + strcpy(io_buffer, message(MSG_PGANOID, id, NULL, isjson)); + else { + api->identify_device(cgpu); + strcpy(io_buffer, message(MSG_PGAIDENT, id, NULL, isjson)); + } +} #endif #ifdef WANT_CPUMINE @@ -2888,6 +2932,7 @@ struct CMDS { { "pga", pgadev, false }, { "pgaenable", pgaenable, true }, { "pgadisable", pgadisable, true }, + { "pgaidentify", pgaidentify, true }, #endif #ifdef WANT_CPUMINE { "cpu", cpudev, false }, diff --git a/driver-bitforce.c b/driver-bitforce.c index 64cc51aca9..c1107feae1 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -99,6 +99,7 @@ static bool bitforce_detect_one(const char *devpath) } BFwrite(fdDev, "ZGX", 3); + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "BFL: Error reading/timeout (ZGX)"); @@ -309,6 +310,7 @@ void bitforce_init(struct cgpu_info *bitforce) do { BFwrite(fdDev, "ZGX", 3); + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { @@ -338,6 +340,37 @@ void bitforce_init(struct cgpu_info *bitforce) mutex_unlock(&bitforce->device_mutex); } +static void bitforce_flash_led(struct cgpu_info *bitforce) +{ + int fdDev = bitforce->device_fd; + + if (!fdDev) + return; + + /* Do not try to flash the led if we're polling for a result to + * minimise the chance of interleaved results */ + if (bitforce->polling) + return; + + /* It is not critical flashing the led so don't get stuck if we + * can't grab the mutex here */ + if (mutex_trylock(&bitforce->device_mutex)) + return; + + BFwrite(fdDev, "ZMX", 3); + + /* Once we've tried - don't do it until told to again */ + bitforce->flash_led = false; + + /* However, this stops anything else getting a reply + * So best to delay any other access to the BFL */ + sleep(4); + + mutex_unlock(&bitforce->device_mutex); + + return; // nothing is returned by the BFL +} + static bool bitforce_get_temp(struct cgpu_info *bitforce) { int fdDev = bitforce->device_fd; @@ -348,16 +381,23 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) return false; /* Do not try to get the temperature if we're polling for a result to - * minimise the change of interleaved results */ + * minimise the chance of interleaved results */ if (bitforce->polling) return true; - /* It is not critical getting temperature so don't get stuck if we + // Flash instead of Temp - doing both can be too slow + if (bitforce->flash_led) { + bitforce_flash_led(bitforce); + return true; + } + + /* It is not critical getting temperature so don't get stuck if we * can't grab the mutex here */ if (mutex_trylock(&bitforce->device_mutex)) return false; BFwrite(fdDev, "ZLX", 3); + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); @@ -414,6 +454,7 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) BFwrite(fdDev, "ZPX", 3); else BFwrite(fdDev, "ZDX", 3); + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (!pdevbuf[0] || !strncasecmp(pdevbuf, "B", 1)) { mutex_unlock(&bitforce->device_mutex); @@ -453,6 +494,7 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) BFwrite(fdDev, ob, 68); } + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); @@ -496,6 +538,7 @@ static int64_t bitforce_get_result(struct thr_info *thr, struct work *work) mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZFX", 3); + pdevbuf[0] = '\0'; BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); @@ -640,6 +683,11 @@ static bool bitforce_get_stats(struct cgpu_info *bitforce) return bitforce_get_temp(bitforce); } +static void bitforce_identify(struct cgpu_info *bitforce) +{ + bitforce->flash_led = true; +} + static bool bitforce_thread_init(struct thr_info *thr) { struct cgpu_info *bitforce = thr->cgpu; @@ -676,6 +724,7 @@ struct device_api bitforce_api = { .reinit_device = bitforce_init, .get_statline_before = get_bitforce_statline_before, .get_stats = bitforce_get_stats, + .identify_device = bitforce_identify, .thread_prepare = bitforce_thread_prepare, .thread_init = bitforce_thread_init, .scanhash = bitforce_scanhash, diff --git a/miner.h b/miner.h index 7234cf6c25..6ac8d93413 100644 --- a/miner.h +++ b/miner.h @@ -239,6 +239,7 @@ struct device_api { void (*get_statline)(char*, struct cgpu_info*); struct api_data *(*get_api_stats)(struct cgpu_info*); bool (*get_stats)(struct cgpu_info*); + void (*identify_device)(struct cgpu_info*); // e.g. to flash a led // Thread-specific functions bool (*thread_prepare)(struct thr_info*); @@ -337,6 +338,7 @@ struct cgpu_info { uint32_t nonces; bool nonce_range; bool polling; + bool flash_led; #endif pthread_mutex_t device_mutex;