Do all writes on avalon with a select() timeout to prevent indefinite blocking and loop if less than desired is written.
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
diff --git a/driver-avalon.c b/driver-avalon.c
index 6902bb9..5619557 100644
--- a/driver-avalon.c
+++ b/driver-avalon.c
@@ -121,19 +121,47 @@ static inline void avalon_create_task(struct avalon_task *at,
memcpy(at->data, work->data + 64, 12);
}
+static int avalon_write(int fd, char *buf, ssize_t len)
+{
+ ssize_t wrote = 0;
+
+ while (len > 0) {
+ struct timeval timeout;
+ ssize_t ret;
+ fd_set wd;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 100000;
+ FD_ZERO(&wd);
+ FD_SET((SOCKETTYPE)fd, &wd);
+ ret = select(fd + 1, NULL, &wd, NULL, &timeout);
+ if (unlikely(ret < 1)) {
+ applog(LOG_WARNING, "Select error on avalon_write");
+ return AVA_SEND_ERROR;
+ }
+ ret = write(fd, buf + wrote, len);
+ if (unlikely(ret < 1)) {
+ applog(LOG_WARNING, "Write error on avalon_write");
+ return AVA_SEND_ERROR;
+ }
+ wrote += ret;
+ len -= ret;
+ }
+
+ return AVA_SEND_OK;
+}
+
static int avalon_send_task(int fd, const struct avalon_task *at,
struct cgpu_info *avalon)
{
- size_t ret;
- int full;
struct timespec p;
uint8_t buf[AVALON_WRITE_SIZE + 4 * AVALON_DEFAULT_ASIC_NUM];
size_t nr_len;
struct avalon_info *info;
uint64_t delay = 32000000; /* Default 32ms for B19200 */
uint32_t nonce_range;
- int i;
+ int ret, i;
if (at->nonce_elf)
nr_len = AVALON_WRITE_SIZE + 4 * at->asic_num;
@@ -182,25 +210,16 @@ static int avalon_send_task(int fd, const struct avalon_task *at,
nr_len = 1;
if (opt_debug) {
applog(LOG_DEBUG, "Avalon: Sent(%u):", (unsigned int)nr_len);
- hexdump((uint8_t *)buf, nr_len);
+ hexdump(buf, nr_len);
}
- ret = write(fd, buf, nr_len);
- if (unlikely(ret != nr_len))
- return AVA_SEND_ERROR;
+ ret = avalon_write(fd, (char *)buf, nr_len);
p.tv_sec = 0;
p.tv_nsec = (long)delay + 4000000;
nanosleep(&p, NULL);
applog(LOG_DEBUG, "Avalon: Sent: Buffer delay: %ld", p.tv_nsec);
- full = avalon_buffer_full(fd);
- applog(LOG_DEBUG, "Avalon: Sent: Buffer full: %s",
- ((full == AVA_BUFFER_FULL) ? "Yes" : "No"));
-
- if (unlikely(full == AVA_BUFFER_FULL))
- return AVA_SEND_BUFFER_FULL;
-
- return AVA_SEND_BUFFER_EMPTY;
+ return ret;
}
static void avalon_decode_nonce(struct thr_info *thr, struct cgpu_info *avalon,
diff --git a/driver-avalon.h b/driver-avalon.h
index 1ba7b7d..297bdda 100644
--- a/driver-avalon.h
+++ b/driver-avalon.h
@@ -120,8 +120,6 @@ struct avalon_info {
#define AVA_SEND_ERROR -1
#define AVA_SEND_OK 0
-#define AVA_SEND_BUFFER_EMPTY 1
-#define AVA_SEND_BUFFER_FULL 2
#define AVA_BUFFER_FULL 0
#define AVA_BUFFER_EMPTY 1