minion - report spi error counts and settings in stats
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
diff --git a/driver-minion.c b/driver-minion.c
index 30cf7f4..aa47e70 100644
--- a/driver-minion.c
+++ b/driver-minion.c
@@ -609,13 +609,13 @@ typedef struct perf_item {
#define ALLOC_PERF_ITEMS 128
#define LIMIT_PERF_ITEMS 0
-// *** 0xff error history - uses max 20 and rolls over
+// *** 0xff error history
typedef struct xff_item {
- struct timeval when;
+ time_t when;
} XFF_ITEM;
-#define ALLOC_XFF_ITEMS 20
-#define LIMIT_XFF_ITEMS 20
+#define ALLOC_XFF_ITEMS 100
+#define LIMIT_XFF_ITEMS 100
#define DATA_WORK(_item) ((WORK_ITEM *)(_item->data))
#define DATA_TASK(_item) ((TASK_ITEM *)(_item->data))
@@ -758,6 +758,7 @@ struct minion_info {
bool spi_reset_io;
int spi_reset_count;
time_t last_spi_reset;
+ uint64_t spi_resets;
// TODO: need to track disabled chips - done?
int chips;
@@ -858,6 +859,11 @@ struct minion_info {
// 0xff history
K_LIST *xfree_list;
K_STORE *xff_list;
+ time_t last_power_cycle;
+ uint64_t power_cycles;
+ time_t last_xff;
+ uint64_t xffs;
+ uint64_t last_displayed_xff;
// Gets reset to zero each time it is used in reporting
int res_err_count[MINION_CHIPS];
@@ -894,6 +900,7 @@ struct minion_info {
#if MINION_ROCKCHIP == 1
static bool minion_toggle_gpio(struct cgpu_info *minioncgpu, int gpionum)
{
+ struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
char pindir[64], ena[64], pin[8], dir[64];
char gpiointvalue[64];
struct stat st;
@@ -956,8 +963,8 @@ static bool minion_toggle_gpio(struct cgpu_info *minioncgpu, int gpionum)
gpionum, errno);
return false;
}
- ret = write(file, MINION_GPIO_DIR_WRITE, (size_t)strlen(MINION_GPIO_DIR_WRITE));
- if (ret != (ssize_t)strlen(MINION_GPIO_DIR_READ)) {
+ ret = write(file, MINION_GPIO_DIR_WRITE, sizeof(MINION_GPIO_DIR_WRITE)-1);
+ if (ret != sizeof(MINION_GPIO_DIR_WRITE)-1) {
if (ret < 0)
err = errno;
else
@@ -965,7 +972,7 @@ static bool minion_toggle_gpio(struct cgpu_info *minioncgpu, int gpionum)
close(file);
applog(LOG_ERR, "%s: failed6 to configure GPIO pin %d (%d:%d)",
minioncgpu->drv->dname, gpionum,
- err, (int)strlen(MINION_GPIO_DIR_READ));
+ err, (int)sizeof(MINION_GPIO_DIR_WRITE)-1);
return false;
}
close(file);
@@ -1003,6 +1010,8 @@ static bool minion_toggle_gpio(struct cgpu_info *minioncgpu, int gpionum)
}
close(fd);
+ minioninfo->last_power_cycle = time(NULL);
+ minioninfo->power_cycles++;
return true;
}
#endif
@@ -1289,6 +1298,7 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
bool fail = false, powercycle = false, show = false;
double lastshow, total;
K_ITEM *xitem;
+ time_t now;
int ret;
#if MINION_SHOW_IO
char dataw[DATA_ALL], datar[DATA_ALL];
@@ -1361,6 +1371,7 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
// Pin back high after I/O
set_pin(minioninfo, pin, true);
}
+ now = time(NULL);
if (ret >= 0 && rbuf[0] == 0xff && rbuf[ret-1] == 0xff &&
(obuf[1] == READ_ADDR(MINION_RES_DATA) || obuf[1] == READ_ADDR(MINION_SYS_FIFO_STA))) {
int i;
@@ -1373,19 +1384,21 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
}
if (fail) {
powercycle = show = false;
+ minioninfo->xffs++;
+ minioninfo->last_xff = now;
if (minioninfo->xfree_list->count > 0)
xitem = k_unlink_head(minioninfo->xfree_list);
else
xitem = k_unlink_tail(minioninfo->xff_list);
- cgtime(&(DATA_XFF(xitem)->when));
+ DATA_XFF(xitem)->when = now;
if (!minioninfo->xff_list->head)
show = true;
else {
// xff_list is full
if (minioninfo->xfree_list->count == 0) {
- total = tdiff(&(DATA_XFF(xitem)->when),
- &(DATA_XFF(minioninfo->xff_list->tail)->when));
+ total = DATA_XFF(xitem)->when -
+ DATA_XFF(minioninfo->xff_list->tail)->when;
if (total <= MINION_POWER_TIME) {
powercycle = true;
// Discard the history
@@ -1397,9 +1410,9 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
}
if (!powercycle) {
- lastshow = tdiff(&(DATA_XFF(xitem)->when),
- &(DATA_XFF(minioninfo->xff_list->head)->when));
- show = (lastshow >= 5.0);
+ lastshow = DATA_XFF(xitem)->when -
+ DATA_XFF(minioninfo->xff_list->head)->when;
+ show = (lastshow >= 5);
}
}
if (xitem)
@@ -1416,14 +1429,12 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
if (*ioseq > 0 && (*ioseq % minioninfo->spi_reset_count) == 0)
minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
} else {
- if (minioninfo->last_spi_reset == 0L)
- minioninfo->last_spi_reset = time(NULL);
+ if (minioninfo->last_spi_reset == 0)
+ minioninfo->last_spi_reset = now;
else {
- time_t now = time(NULL);
- if ((now - minioninfo->last_spi_reset) >= minioninfo->spi_reset_count) {
- minioninfo->last_spi_reset = now;
+ if ((now - minioninfo->last_spi_reset) >= minioninfo->spi_reset_count)
minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
- }
+ minioninfo->last_spi_reset = now;
}
}
}
@@ -1437,8 +1448,10 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
if (fail) {
if (powercycle) {
- applog(LOG_ERR, "%s%d: power cycling ioctl %"PRIu64,
- minioncgpu->drv->name, minioncgpu->device_id, *ioseq);
+ applog(LOG_ERR, "%s%d: power cycle ioctl %"PRIu64" (%"PRIu64")",
+ minioncgpu->drv->name, minioncgpu->device_id, *ioseq,
+ minioninfo->xffs - minioninfo->last_displayed_xff);
+ minioninfo->last_displayed_xff = minioninfo->xffs;
} else if (show) {
char *what = "unk";
switch (obuf[1]) {
@@ -1449,9 +1462,10 @@ static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minionin
what = "fifo";
break;
}
- applog(LOG_ERR, "%s%d: resetting ioctl %"PRIu64" %s returned all 0xff",
+ applog(LOG_ERR, "%s%d: reset ioctl %"PRIu64" %s all 0xff (%"PRIu64")",
minioncgpu->drv->name, minioncgpu->device_id,
- *ioseq, what);
+ *ioseq, what, minioninfo->xffs - minioninfo->last_displayed_xff);
+ minioninfo->last_displayed_xff = minioninfo->xffs;
}
}
@@ -1978,6 +1992,7 @@ static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *mi
minioninfo->spifd = open(minioncgpu->device_path, O_RDWR);
if (minioninfo->spifd < 0)
goto bad_out;
+ minioninfo->spi_resets++;
} else {
for (i = 0; minion_modules[i]; i++) {
snprintf(buf, sizeof(buf), "modprobe %s", minion_modules[i]);
@@ -4931,6 +4946,22 @@ static struct api_data *minion_api_stats(struct cgpu_info *minioncgpu)
root = api_add_int(root, "RFree Count", &(minioninfo->rfree_list->count), true);
root = api_add_int(root, "RNonce Count", &(minioninfo->rnonce_list->count), true);
+ root = api_add_int(root, "XFree Count", &(minioninfo->xfree_list->count), true);
+ root = api_add_int(root, "XFF Count", &(minioninfo->xff_list->count), true);
+ root = api_add_uint64(root, "XFFs", &(minioninfo->xffs), true);
+ root = api_add_uint64(root, "SPI Resets", &(minioninfo->spi_resets), true);
+ root = api_add_uint64(root, "Power Cycles", &(minioninfo->power_cycles), true);
+
+ root = api_add_int(root, "Chip Report", &opt_minion_chipreport, true);
+ root = api_add_int(root, "LED Count", &opt_minion_ledcount, true);
+ root = api_add_int(root, "LED Limit", &opt_minion_ledlimit, true);
+ bool b = !opt_minion_noautofreq;
+ root = api_add_bool(root, "Auto Freq", &b, true);
+ root = api_add_int(root, "SPI Delay", &opt_minion_spidelay, true);
+ root = api_add_bool(root, "SPI Reset I/O", &(minioninfo->spi_reset_io), true);
+ root = api_add_int(root, "SPI Reset", &(minioninfo->spi_reset_count), true);
+ root = api_add_int(root, "SPI Reset Sleep", &opt_minion_spisleep, true);
+
#if DO_IO_STATS
#define sta_api(_name, _iostat) \
do { \