minion - allow resetting a chip via the API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
diff --git a/API-README b/API-README
index d4db726..62d3c47 100644
--- a/API-README
+++ b/API-README
@@ -442,6 +442,7 @@ The list of requests - a (*) means it requires privileged access - and replies:
The current options are:
AVA+BTB opt=freq val=256 to 1024 - chip frequency
BTB opt=millivolts val=1000 to 1400 - corevoltage
+ MBA opt=reset val=0 to chipcount - reset a chip
lcd LCD An all-in-one short status summary of the miner
e.g. Elapsed,GHS av,GHS 5m,GHS 5s,Temp,
diff --git a/driver-minion.c b/driver-minion.c
index afabc4e..e87fbd0 100644
--- a/driver-minion.c
+++ b/driver-minion.c
@@ -742,6 +742,7 @@ struct minion_info {
uint64_t nonces_recovered[MINION_CHIPS];
struct timeval last_reset[MINION_CHIPS];
double do_reset[MINION_CHIPS];
+ bool flag_reset[MINION_CHIPS];
// Work items
K_LIST *wfree_list;
@@ -2167,6 +2168,44 @@ unalloc:
free(minioncgpu);
}
+static char *minion_set(struct cgpu_info *minioncgpu, char *option, char *setting, char *replybuf)
+{
+ struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
+ int chip;
+
+ if (strcasecmp(option, "help") == 0) {
+ sprintf(replybuf, "reset: chip 0-%d",
+ minioninfo->chips - 1);
+ return replybuf;
+ }
+
+ if (strcasecmp(option, "reset") == 0) {
+ if (!setting || !*setting) {
+ sprintf(replybuf, "missing chip to reset");
+ return replybuf;
+ }
+
+ chip = atoi(setting);
+ if (chip < 0 || chip >= minioninfo->chips) {
+ sprintf(replybuf, "invalid reset: chip '%s' valid range 0-%d",
+ setting,
+ minioninfo->chips);
+ return replybuf;
+ }
+
+ if (!minioninfo->has_chip[chip]) {
+ sprintf(replybuf, "unable to reset chip %d - chip disabled",
+ chip);
+ return replybuf;
+ }
+ minioninfo->flag_reset[chip] = true;
+ return NULL;
+ }
+
+ sprintf(replybuf, "Unknown option: %s", option);
+ return replybuf;
+}
+
static void minion_identify(__maybe_unused struct cgpu_info *minioncgpu)
{
// flash a led
@@ -3787,11 +3826,25 @@ static void chip_report(struct cgpu_info *minioncgpu)
minioninfo->do_reset[chip] = 0.0;
memcpy(&(minioninfo->last_reset[chip]), &now, sizeof(now));
init_chip(minioncgpu, minioninfo, chip);
+ minioninfo->flag_reset[chip] = false;
}
}
}
memcpy(&(minioninfo->chip_chk), &now, sizeof(now));
}
+
+ for (chip = 0; chip < (int)MINION_CHIPS; chip++) {
+ if (minioninfo->has_chip[chip]) {
+ if (minioninfo->flag_reset[chip]) {
+ applog(LOG_WARNING, "%s%d: Chip %d flagged - resetting ...",
+ minioncgpu->drv->name, minioncgpu->device_id,
+ chip);
+ memcpy(&(minioninfo->last_reset[chip]), &now, sizeof(now));
+ init_chip(minioncgpu, minioninfo, chip);
+ minioninfo->flag_reset[chip] = false;
+ }
+ }
+ }
}
static int64_t minion_scanwork(__maybe_unused struct thr_info *thr)
@@ -4178,6 +4231,7 @@ struct device_drv minion_drv = {
#ifdef LINUX
.get_api_stats = minion_api_stats,
.get_statline_before = minion_get_statline_before,
+ .set_device = minion_set,
.identify_device = minion_identify,
.thread_prepare = minion_thread_prepare,
.hash_work = hash_queued_work,