Merge pull request #625 from kanoi/master minion - 'reset' SPI when getting errors & mutex lock getaddrinfo
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 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
diff --git a/cgminer.c b/cgminer.c
index b0330b3..c783327 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -306,6 +306,7 @@ static pthread_mutex_t sshare_lock;
pthread_rwlock_t netacc_lock;
pthread_rwlock_t mining_thr_lock;
pthread_rwlock_t devices_lock;
+pthread_mutex_t getaddr_lock;
static pthread_mutex_t lp_lock;
static pthread_cond_t lp_cond;
@@ -9261,6 +9262,7 @@ int main(int argc, char *argv[])
rwlock_init(&netacc_lock);
rwlock_init(&mining_thr_lock);
rwlock_init(&devices_lock);
+ mutex_init(&getaddr_lock);
mutex_init(&lp_lock);
if (unlikely(pthread_cond_init(&lp_cond, NULL)))
diff --git a/driver-minion.c b/driver-minion.c
index 876ab2c..2bb3831 100644
--- a/driver-minion.c
+++ b/driver-minion.c
@@ -67,8 +67,11 @@ static int minion_memory_addr = BCM2835_GPIO_BASE;
#define MINION_SPI_BUS 0
#define MINION_SPI_CHIP 0
-//#define MINION_SPI_SPEED 2000000
+#if MINION_ROCKCHIP == 0
#define MINION_SPI_SPEED 8000000
+#else
+#define MINION_SPI_SPEED 500000
+#endif
#define MINION_SPI_BUFSIZ 1024
static struct minion_select_pins {
@@ -709,6 +712,7 @@ static double time_bands[] = { 0.1, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0 };
#define TIME_BANDS ((int)(sizeof(time_bands)/sizeof(double)))
struct minion_info {
+ struct thr_info *thr;
struct thr_info spiw_thr;
struct thr_info spir_thr;
struct thr_info res_thr;
@@ -1120,11 +1124,14 @@ static void init_pins(struct minion_info *minioninfo)
#define EXTRA_LOG_IO 0
-static int __do_ioctl(struct minion_info *minioninfo, int pin, uint8_t *obuf,
- uint32_t osiz, uint8_t *rbuf, uint32_t rsiz,
- uint64_t *ioseq, MINION_FFL_ARGS)
+static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int bus, int chip, bool reset);
+
+static int __do_ioctl(struct cgpu_info *minioncgpu, struct minion_info *minioninfo,
+ int pin, uint8_t *obuf, uint32_t osiz, uint8_t *rbuf,
+ uint32_t rsiz, uint64_t *ioseq, MINION_FFL_ARGS)
{
struct spi_ioc_transfer tran;
+ bool fail = false;
int ret;
#if MINION_SHOW_IO
char dataw[DATA_ALL], datar[DATA_ALL];
@@ -1197,12 +1204,31 @@ static int __do_ioctl(struct minion_info *minioninfo, int pin, uint8_t *obuf,
// Pin back high after I/O
set_pin(minioninfo, pin, true);
}
+ if (ret >= 0 && rbuf[0] == 0xff && rbuf[ret-1] == 0xff &&
+ obuf[1] == READ_ADDR(MINION_RES_DATA)) {
+ int i;
+ fail = true;
+ for (i = 1; i < ret-2; i++) {
+ if (rbuf[i] != 0xff) {
+ fail = false;
+ break;
+ }
+ }
+ if (fail)
+ minion_init_spi(minioncgpu, minioninfo, 0, 0, true);
+ }
mutex_unlock(&(minioninfo->spi_lock));
IO_STAT_NOW(&lfin);
IO_STAT_NOW(&tsd);
IO_STAT_STORE(&sta, &fin, &lsta, &lfin, &tsd, obuf, osiz, ret, 1);
+ if (fail) {
+ applog(LOG_ERR, "%s%d: ioctl %"PRIu64" returned all 0xff - resetting",
+ minioncgpu->drv->name, minioncgpu->device_id,
+ *ioseq);
+ }
+
#if MINION_SHOW_IO
if (ret > 0) {
buf = bin2hex((unsigned char *)&(datar[DATA_OFF]), ret);
@@ -1254,7 +1280,7 @@ static int __do_ioctl(struct minion_info *minioninfo, int pin, uint8_t *obuf,
#if 1
#define do_ioctl(_pin, _obuf, _osiz, _rbuf, _rsiz, _ioseq) \
- __do_ioctl(minioninfo, _pin, _obuf, _osiz, _rbuf, \
+ __do_ioctl(minioncgpu, minioninfo, _pin, _obuf, _osiz, _rbuf, \
_rsiz, _ioseq, MINION_FFL_HERE)
#else
#define do_ioctl(_pin, _obuf, _osiz, _rbuf, _rsiz, _ioseq) \
@@ -1273,9 +1299,9 @@ static int _do_ioctl(struct minion_info *minioninfo, int pin, uint8_t *obuf, uin
head->reg = READ_ADDR(MINION_SYS_FIFO_STA);
SET_HEAD_SIZ(head, DATA_SIZ);
siz = HSIZE() + DATA_SIZ;
- __do_ioctl(minioninfo, pin, buf1, siz, buf2, MINION_CORE_SIZ, ioseq, MINION_FFL_PASS);
+ __do_ioctl(minioncgpu, minioninfo, pin, buf1, siz, buf2, MINION_CORE_SIZ, ioseq, MINION_FFL_PASS);
- return __do_ioctl(minioninfo, pin, obuf, osiz, rbuf, rsiz, ioseq, MINION_FFL_PASS);
+ return __do_ioctl(minioncgpu, minioninfo, pin, obuf, osiz, rbuf, rsiz, ioseq, MINION_FFL_PASS);
}
#endif
@@ -1713,33 +1739,42 @@ static struct {
{ -1, -1 }
};
-static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int bus, int chip)
+static bool minion_init_spi(struct cgpu_info *minioncgpu, struct minion_info *minioninfo, int bus, int chip, bool reset)
{
int i, err, data;
char buf[64];
- for (i = 0; minion_modules[i]; i++) {
- snprintf(buf, sizeof(buf), "modprobe %s", minion_modules[i]);
- err = system(buf);
- if (err) {
- applog(LOG_ERR, "%s: failed to modprobe %s (%d) - you need to be root?",
+ if (reset) {
+ // TODO: maybe slow it down?
+ close(minioninfo->spifd);
+ cgsleep_ms(100);
+ minioninfo->spifd = open(minioncgpu->device_path, O_RDWR);
+ if (minioninfo->spifd < 0)
+ goto bad_out;
+ } else {
+ for (i = 0; minion_modules[i]; i++) {
+ snprintf(buf, sizeof(buf), "modprobe %s", minion_modules[i]);
+ err = system(buf);
+ if (err) {
+ applog(LOG_ERR, "%s: failed to modprobe %s (%d) - you need to be root?",
+ minioncgpu->drv->dname,
+ minion_modules[i], err);
+ goto bad_out;
+ }
+ }
+
+ snprintf(buf, sizeof(buf), "/dev/spidev%d.%d", bus, chip);
+ minioninfo->spifd = open(buf, O_RDWR);
+ if (minioninfo->spifd < 0) {
+ applog(LOG_ERR, "%s: failed to open spidev (%d)",
minioncgpu->drv->dname,
- minion_modules[i], err);
+ errno);
goto bad_out;
}
- }
- snprintf(buf, sizeof(buf), "/dev/spidev%d.%d", bus, chip);
- minioninfo->spifd = open(buf, O_RDWR);
- if (minioninfo->spifd < 0) {
- applog(LOG_ERR, "%s: failed to open spidev (%d)",
- minioncgpu->drv->dname,
- errno);
- goto bad_out;
+ minioncgpu->device_path = strdup(buf);
}
- minioncgpu->device_path = strdup(buf);
-
for (i = 0; minion_ioc[i].value != -1; i++) {
data = minion_ioc[i].value;
err = ioctl(minioninfo->spifd, minion_ioc[i].request, (void *)&data);
@@ -2150,7 +2185,7 @@ static void minion_detect(bool hotplug)
quithere(1, "Failed to calloc minioninfo");
minioncgpu->device_data = (void *)minioninfo;
- if (!minion_init_spi(minioncgpu, minioninfo, MINION_SPI_BUS, MINION_SPI_CHIP))
+ if (!minion_init_spi(minioncgpu, minioninfo, MINION_SPI_BUS, MINION_SPI_CHIP, false))
goto unalloc;
#if ENABLE_INT_NONO
@@ -3254,7 +3289,7 @@ static void *minion_results(void *userdata)
{
struct cgpu_info *minioncgpu = (struct cgpu_info *)userdata;
struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
- struct thr_info *thr = minioncgpu->thr[0];
+ struct thr_info *thr;
int chip, core;
uint32_t task_id;
uint32_t nonce;
@@ -3275,6 +3310,8 @@ static void *minion_results(void *userdata)
cgsleep_ms(3);
}
+ thr = minioninfo->thr;
+
while (minioncgpu->shutdown == false) {
if (!oldest_nonce(minioncgpu, &chip, &core, &task_id, &nonce,
&no_nonce, &when, &another, &task_id2, &nonce2)) {
@@ -3785,6 +3822,7 @@ static bool minion_thread_prepare(struct thr_info *thr)
struct cgpu_info *minioncgpu = thr->cgpu;
struct minion_info *minioninfo = (struct minion_info *)(minioncgpu->device_data);
+ minioninfo->thr = thr;
/*
* SPI/ioctl write thread
*/
diff --git a/miner.h b/miner.h
index f8899c8..58aba3c 100644
--- a/miner.h
+++ b/miner.h
@@ -1078,6 +1078,7 @@ extern pthread_mutex_t console_lock;
extern cglock_t ch_lock;
extern pthread_rwlock_t mining_thr_lock;
extern pthread_rwlock_t devices_lock;
+extern pthread_mutex_t getaddr_lock;
extern pthread_mutex_t restart_lock;
extern pthread_cond_t restart_cond;
diff --git a/util.c b/util.c
index 4f3a3d4..634e23c 100644
--- a/util.c
+++ b/util.c
@@ -2240,7 +2240,7 @@ static bool socks4_negotiate(struct pool *pool, int sockd, bool socks4a)
unsigned short port;
in_addr_t inp;
char buf[515];
- int i, len;
+ int i, len, ret;
buf[0] = 0x04;
buf[1] = 0x01;
@@ -2262,7 +2262,10 @@ static bool socks4_negotiate(struct pool *pool, int sockd, bool socks4a)
servinfo = &servinfobase;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; /* IPV4 only */
- if (!getaddrinfo(pool->sockaddr_url, NULL, &hints, &servinfo)) {
+ mutex_lock(&getaddr_lock);
+ ret = getaddrinfo(pool->sockaddr_url, NULL, &hints, &servinfo);
+ mutex_unlock(&getaddr_lock);
+ if (ret == 0) {
struct sockaddr_in *saddr_in = (struct sockaddr_in *)servinfo->ai_addr;
inp = ntohl(saddr_in->sin_addr.s_addr);
@@ -2348,7 +2351,7 @@ static bool setup_stratum_socket(struct pool *pool)
{
struct addrinfo servinfobase, *servinfo, *hints, *p;
char *sockaddr_url, *sockaddr_port;
- int sockd;
+ int sockd, ret;
mutex_lock(&pool->stratum_lock);
pool->stratum_active = false;
@@ -2376,7 +2379,10 @@ static bool setup_stratum_socket(struct pool *pool)
sockaddr_url = pool->sockaddr_url;
sockaddr_port = pool->stratum_port;
}
- if (getaddrinfo(sockaddr_url, sockaddr_port, hints, &servinfo) != 0) {
+ mutex_lock(&getaddr_lock);
+ ret = getaddrinfo(sockaddr_url, sockaddr_port, hints, &servinfo);
+ mutex_unlock(&getaddr_lock);
+ if (ret != 0) {
if (!pool->probed) {
applog(LOG_WARNING, "Failed to resolve (?wrong URL) %s:%s",
sockaddr_url, sockaddr_port);