diff --git a/api.c b/api.c index 3e6501af..268d90a7 100644 --- a/api.c +++ b/api.c @@ -167,7 +167,6 @@ static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; static const char *DISABLED = "Disabled"; static const char *ALIVE = "Alive"; -static const char *IDLE = "Idle"; static const char *REJECTING = "Rejecting"; static const char *UNKNOWN = "Unknown"; #define _DYNAMIC "D" @@ -466,7 +465,7 @@ struct CODES { { SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported succeess" }, { SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" }, { SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" }, - { SEVERITY_SUCC, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, + { SEVERITY_ERR, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, { SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" }, { SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" }, { SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" }, @@ -880,7 +879,7 @@ static void pgastatus(int pga, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (cgpu->deven == DEV_ENABLED) + if (cgpu->deven != DEV_DISABLED) enabled = (char *)YES; else enabled = (char *)NO; @@ -891,8 +890,6 @@ static void pgastatus(int pga, bool isjson) status = (char *)SICK; else if (cgpu->status == LIFE_NOSTART) status = (char *)NOSTART; - else if (cgpu->deven == DEV_IDLE) - status = (char *)IDLE; else status = (char *)ALIVE; @@ -1095,7 +1092,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven == DEV_ENABLED) { + if (cgpu->deven != DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); return; } @@ -1146,12 +1143,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven != DEV_ENABLED) { + if (cgpu->deven == DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); return; } - cgpu->deven = DEV_IDLE; + cgpu->deven = DEV_DISABLED; strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } @@ -1982,13 +1979,12 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { - char filename[PATH_MAX]; FILE *fcfg; char *ptr; if (param == NULL || *param == '\0') { - default_save_file(filename); - param = filename; + strcpy(io_buffer, message(MSG_MISFN, 0, NULL, isjson)); + return; } fcfg = fopen(param, "w"); @@ -2570,3 +2566,4 @@ die: mutex_unlock(&quit_restart_lock); } + diff --git a/cgminer.c b/cgminer.c index ad1259e3..77284cdf 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3918,7 +3918,7 @@ void *miner_thread(void *userdata) tv_lastupdate = tv_end; } - if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) { + if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) { applog(LOG_WARNING, "Thread %d being disabled", thr_id); disabled: mythr->rolling = mythr->cgpu->rolling = 0; @@ -4274,13 +4274,17 @@ static void *watchdog_thread(void __maybe_unused *userdata) } } -#ifdef HAVE_OPENCL for (i = 0; i < total_devices; ++i) { struct cgpu_info *cgpu = devices[i]; struct thr_info *thr = cgpu->thread; enum dev_enable *denable; int gpu; + + if (cgpu->api->get_stats) { + cgpu->api->get_stats(cgpu); + } +#ifdef HAVE_OPENCL if (cgpu->api != &opencl_api) continue; /* Use only one thread per device to determine if the GPU is healthy */ @@ -4300,6 +4304,7 @@ static void *watchdog_thread(void __maybe_unused *userdata) temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune); } #endif + /* Thread is waiting on getwork or disabled */ if (thr->getwork || *denable == DEV_DISABLED) continue; @@ -4347,8 +4352,9 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (opt_restart) reinit_device(thr->cgpu); } +#endif /* HAVE_OPENCL */ } -#endif + } return NULL; diff --git a/driver-bitforce.c b/driver-bitforce.c index 00eeb9c5..e930d149 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -133,6 +133,8 @@ static bool bitforce_detect_one(const char *devpath) s[0] = '\0'; bitforce->name = strdup(pdevbuf + 7); } + + mutex_init(&bitforce->dev_lock); return add_cgpu(bitforce); } @@ -284,8 +286,11 @@ static bool bitforce_init(struct cgpu_info *bitforce) bitforce->device_fd = fdDev; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZGX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); + if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZGX)"); return false; @@ -311,8 +316,11 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZLX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); + if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading temp from BitForce (ZLX)"); return false; @@ -322,8 +330,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) if (temp > 0) { bitforce->temp = temp; if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, setting idle", bitforce->api->name, bitforce->device_id); - bitforce->deven = DEV_IDLE; + applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); + bitforce->deven = DEV_RECOVER; bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; @@ -342,27 +350,30 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; char *s; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZDX)"); + mutex_unlock(&bitforce->dev_lock); return false; } if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf); + mutex_unlock(&bitforce->dev_lock); return false; } - memcpy(ob + 8, work->midstate, 32); memcpy(ob + 8 + 32, work->data + 64, 12); + BFwrite(fdDev, ob, 60); if (opt_debug) { s = bin2hex(ob + 8, 44); applog(LOG_DEBUG, "BitForce block data: %s", s); free(s); } - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (block data)"); return false; @@ -386,10 +397,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) i = BITFORCE_SLEEP_MS; while (i < BITFORCE_TIMEOUT_MS) { + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZFX)"); + mutex_unlock(&bitforce->dev_lock); return 0; } if (pdevbuf[0] != 'B') @@ -410,7 +424,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') return 0xffffffff; /* No valid nonce found */ - else if (pdevbuf[0] == 'I') + else if (pdevbuf[0] == 'I') return 1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf); @@ -434,12 +448,25 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) return 0xffffffff; } +static void bitforce_shutdown(struct thr_info *thr) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; + + BFclose(fdDev); +} + static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; bool dev_enabled = (bitforce->deven == DEV_ENABLED); static enum dev_enable last_dev_state = DEV_ENABLED; + if (bitforce->deven == DEV_DISABLED) { + bitforce_shutdown(thr); + return 1; + } + // if device has just gone from disabled to enabled, re-initialise it if (last_dev_state == DEV_DISABLED && dev_enabled) bitforce_init(bitforce); @@ -448,9 +475,6 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!bitforce_send_work(thr, work)) return 0; - if (!bitforce_get_temp(bitforce)) - return 0; - usleep(BITFORCE_SLEEP_US); if (dev_enabled) @@ -459,12 +483,9 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 return 1; } -static void bitforce_shutdown(struct thr_info *thr) +static bool bitforce_get_stats(struct cgpu_info *bitforce) { - struct cgpu_info *bitforce = thr->cgpu; - int fdDev = bitforce->device_fd; - - BFclose(fdDev); + return bitforce_get_temp(bitforce); } struct device_api bitforce_api = { @@ -472,6 +493,7 @@ struct device_api bitforce_api = { .name = "BFL", .api_detect = bitforce_detect, .get_statline_before = get_bitforce_statline_before, + .get_stats = bitforce_get_stats, .thread_prepare = bitforce_thread_prepare, .scanhash = bitforce_scanhash, .thread_shutdown = bitforce_shutdown diff --git a/driver-icarus.c b/driver-icarus.c index 630b66b3..75ab5e3f 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -566,12 +566,6 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, uint32_t values; uint64_t hash_count_range; - /* Device developer can make use of idle state, until then, disable and return */ - if (thr->cgpu->deven == DEV_IDLE) { - thr->cgpu->deven = DEV_DISABLED; - return 1; - } - elapsed.tv_sec = elapsed.tv_usec = 0; icarus = thr->cgpu; diff --git a/driver-ztex.c b/driver-ztex.c index 91f7a7bd..c881cd7d 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -199,12 +199,6 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, bool overflow, found, rv; struct libztex_hash_data hdata[GOLDEN_BACKLOG]; - /* Device developer can make use of idle state, until then, disable and return */ - if (thr->cgpu->deven == DEV_IDLE) { - thr->cgpu->deven = DEV_DISABLED; - return 1; - } - ztex = thr->cgpu->device_ztex; memcpy(sendbuf, work->data + 64, 12); diff --git a/miner.h b/miner.h index f5f7122c..2251031b 100644 --- a/miner.h +++ b/miner.h @@ -235,6 +235,7 @@ struct device_api { void (*get_statline_before)(char*, struct cgpu_info*); void (*get_statline)(char*, struct cgpu_info*); void (*get_api_stats)(char*, struct cgpu_info*, bool); + bool (*get_stats)(struct cgpu_info*); // Thread-specific functions bool (*thread_prepare)(struct thr_info*); @@ -250,7 +251,6 @@ enum dev_enable { DEV_ENABLED, DEV_DISABLED, DEV_RECOVER, - DEV_IDLE, }; enum cl_kernels { @@ -366,6 +366,8 @@ struct cgpu_info { int dev_thermal_cutoff_count; struct cgminer_stats cgminer_stats; + + pthread_mutex_t dev_lock; }; extern bool add_cgpu(struct cgpu_info*);