From 2f75a5d89e9d9ef1a8dba409b1a69582a7107c95 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 6 Apr 2013 01:03:21 +1100 Subject: [PATCH] Simplify avalon scanhash code using the new find_queued_work_bymidstate function. Partially works only. --- driver-avalon.c | 133 ++++++++++++++---------------------------------- driver-avalon.h | 4 -- 2 files changed, 39 insertions(+), 98 deletions(-) diff --git a/driver-avalon.c b/driver-avalon.c index 8af3c4cc..01970626 100644 --- a/driver-avalon.c +++ b/driver-avalon.c @@ -272,6 +272,7 @@ static int avalon_get_result(int fd, struct avalon_result *ar, memset(result, 0, AVALON_READ_SIZE); ret = avalon_gets(fd, result, read_count, thr, tv_finish); + memset(ar, 0, sizeof(struct avalon_result)); if (ret == AVA_GETS_OK) { if (opt_debug) { applog(LOG_DEBUG, "Avalon: get:"); @@ -283,35 +284,28 @@ static int avalon_get_result(int fd, struct avalon_result *ar, return ret; } -static int avalon_decode_nonce(struct thr_info *thr, struct work **work, - struct avalon_result *ar, uint32_t *nonce) +static bool avalon_decode_nonce(struct thr_info *thr, struct avalon_result *ar, + uint32_t *nonce) { struct cgpu_info *avalon; struct avalon_info *info; int avalon_get_work_count, i; - - if (unlikely(!work)) - return -1; + struct work *work; avalon = thr->cgpu; - info = avalon_info[avalon->device_id]; - avalon_get_work_count = info->miner_count; + if (unlikely(!avalon->works)) + return false; - for (i = 0; i < avalon_get_work_count; i++) { - if (work[i] && - !memcmp(ar->data, work[i]->data + 64, 12) && - !memcmp(ar->midstate, work[i]->midstate, 32)) - break; - } - if (i == avalon_get_work_count) - return -1; + work = find_queued_work_bymidstate(avalon, ar->midstate, 32, ar->data, 64, 12); + if (!work) + return false; + info = avalon_info[avalon->device_id]; info->matching_work[i]++; *nonce = htole32(ar->nonce); + submit_nonce(thr, work, *nonce); - applog(LOG_DEBUG, "Avalon: match to work[%d](%p): %d",i, work[i], - info->matching_work[i]); - return i; + return true; } static int avalon_reset(int fd, struct avalon_result *ar) @@ -661,16 +655,18 @@ static bool avalon_prepare(struct thr_info *thr) return true; } -static void avalon_free_work(struct thr_info *thr, struct work **works) +static void avalon_free_work(struct thr_info *thr) { struct cgpu_info *avalon; struct avalon_info *info; + struct work **works; int i; - if (unlikely(!works)) - return; - avalon = thr->cgpu; + avalon->queued = 0; + if (unlikely(!avalon->works)) + return; + works = avalon->works; info = avalon_info[avalon->device_id]; for (i = 0; i < info->miner_count; i++) { @@ -687,6 +683,7 @@ static void do_avalon_close(struct thr_info *thr) struct cgpu_info *avalon = thr->cgpu; struct avalon_info *info = avalon_info[avalon->device_id]; + avalon_free_work(thr); sleep(1); avalon_reset(avalon->device_fd, &ar); avalon_idle(avalon); @@ -694,10 +691,6 @@ static void do_avalon_close(struct thr_info *thr) avalon->device_fd = -1; info->no_matching_work = 0; - avalon_free_work(thr, info->bulk0); - avalon_free_work(thr, info->bulk1); - avalon_free_work(thr, info->bulk2); - avalon_free_work(thr, info->bulk3); } static inline void record_temp_fan(struct avalon_info *info, struct avalon_result *ar, float *temp_avg) @@ -781,12 +774,11 @@ static int64_t avalon_scanhash(struct thr_info *thr) struct cgpu_info *avalon; struct work **works; int fd, ret, full; - int64_t scanret = 0; struct avalon_info *info; struct avalon_task at; struct avalon_result ar; - int i, work_i0, work_i1, work_i2, work_i3; + int i; int avalon_get_work_count; struct timeval tv_start, tv_finish, elapsed; @@ -806,8 +798,7 @@ static int64_t avalon_scanhash(struct thr_info *thr) avalon->device_id); dev_error(avalon, REASON_DEV_COMMS_ERROR); /* fail the device if the reopen attempt fails */ - scanret = -1; - goto out; + return -1; } } fd = avalon->device_fd; @@ -815,15 +806,6 @@ static int64_t avalon_scanhash(struct thr_info *thr) tcflush(fd, TCOFLUSH); #endif - for (i = 0; i < avalon_get_work_count; i++) { - info->bulk0[i] = info->bulk1[i]; - info->bulk1[i] = info->bulk2[i]; - info->bulk2[i] = info->bulk3[i]; - info->bulk3[i] = works[i]; - applog(LOG_DEBUG, "Avalon: bulk0/1/2 buffer [%d]: %p, %p, %p, %p", - i, info->bulk0[i], info->bulk1[i], info->bulk2[i], info->bulk3[i]); - } - i = 0; while (true) { avalon_init_task(&at, 0, 0, info->fan_pwm, @@ -835,10 +817,6 @@ static int64_t avalon_scanhash(struct thr_info *thr) (ret == AVA_SEND_BUFFER_EMPTY && (i + 1 == avalon_get_work_count) && first_try))) { - avalon_free_work(thr, info->bulk0); - avalon_free_work(thr, info->bulk1); - avalon_free_work(thr, info->bulk2); - avalon_free_work(thr, info->bulk3); do_avalon_close(thr); applog(LOG_ERR, "AVA%i: Comms error(buffer)", avalon->device_id); @@ -846,12 +824,11 @@ static int64_t avalon_scanhash(struct thr_info *thr) first_try = 0; sleep(1); avalon_init(avalon); - goto out; /* This should never happen */ + return 0; /* This should never happen */ } if (ret == AVA_SEND_BUFFER_EMPTY && (i + 1 == avalon_get_work_count)) { first_try = 1; - ret = 0xffffffff; - goto out; + return 0xffffffff; } works[i]->blk.nonce = 0xffffffff; @@ -871,8 +848,6 @@ static int64_t avalon_scanhash(struct thr_info *thr) result_wrong = 0; hash_count = 0; while (true) { - work_i0 = work_i1 = work_i2 = work_i3 = -1; - full = avalon_buffer_full(fd); applog(LOG_DEBUG, "Avalon: Buffer full: %s", ((full == AVA_BUFFER_FULL) ? "Yes" : "No")); @@ -881,15 +856,11 @@ static int64_t avalon_scanhash(struct thr_info *thr) ret = avalon_get_result(fd, &ar, thr, &tv_finish); if (unlikely(ret == AVA_GETS_ERROR)) { - avalon_free_work(thr, info->bulk0); - avalon_free_work(thr, info->bulk1); - avalon_free_work(thr, info->bulk2); - avalon_free_work(thr, info->bulk3); do_avalon_close(thr); applog(LOG_ERR, "AVA%i: Comms error(read)", avalon->device_id); dev_error(avalon, REASON_DEV_COMMS_ERROR); - goto out; + return 0; } if (unlikely(ret == AVA_GETS_TIMEOUT)) { timersub(&tv_finish, &tv_start, &elapsed); @@ -898,40 +869,22 @@ static int64_t avalon_scanhash(struct thr_info *thr) continue; } if (unlikely(ret == AVA_GETS_RESTART)) { - avalon_free_work(thr, info->bulk0); - avalon_free_work(thr, info->bulk1); - avalon_free_work(thr, info->bulk2); - avalon_free_work(thr, info->bulk3); break; } result_count++; - work_i0 = avalon_decode_nonce(thr, info->bulk0, &ar, &nonce); - if (work_i0 < 0) { - work_i1 = avalon_decode_nonce(thr, info->bulk1, &ar, &nonce); - if (work_i1 < 0) { - work_i2 = avalon_decode_nonce(thr, info->bulk2, &ar, &nonce); - if (work_i2 < 0) { - work_i3 = avalon_decode_nonce(thr, info->bulk3, &ar, &nonce); - if (work_i3 < 0) { - info->no_matching_work++; - result_wrong++; - - if (opt_debug) { - timersub(&tv_finish, &tv_start, &elapsed); - applog(LOG_DEBUG,"Avalon: no matching work: %d" - " (%ld.%06lds)", info->no_matching_work, - elapsed.tv_sec, elapsed.tv_usec); - } - continue; - } else - submit_nonce(thr, info->bulk3[work_i3], nonce); - } else - submit_nonce(thr, info->bulk2[work_i2], nonce); - } else - submit_nonce(thr, info->bulk1[work_i1], nonce); - } else - submit_nonce(thr, info->bulk0[work_i0], nonce); + if (!avalon_decode_nonce(thr, &ar, &nonce)) { + info->no_matching_work++; + result_wrong++; + + if (opt_debug) { + timersub(&tv_finish, &tv_start, &elapsed); + applog(LOG_DEBUG,"Avalon: no matching work: %d" + " (%ld.%06lds)", info->no_matching_work, + elapsed.tv_sec, elapsed.tv_usec); + } + continue; + } hash_count += nonce; if (opt_debug) { @@ -945,10 +898,6 @@ static int64_t avalon_scanhash(struct thr_info *thr) if (result_wrong && result_count == result_wrong) { /* This mean FPGA controller give all wrong result * try to reset the Avalon */ - avalon_free_work(thr, info->bulk0); - avalon_free_work(thr, info->bulk1); - avalon_free_work(thr, info->bulk2); - avalon_free_work(thr, info->bulk3); do_avalon_close(thr); applog(LOG_ERR, "AVA%i: FPGA controller mess up", avalon->device_id); @@ -956,10 +905,10 @@ static int64_t avalon_scanhash(struct thr_info *thr) do_avalon_close(thr); sleep(1); avalon_init(avalon); - goto out; + return 0; } - avalon_free_work(thr, info->bulk0); + avalon_free_work(thr); record_temp_fan(info, &ar, &(avalon->temp)); applog(LOG_INFO, @@ -986,11 +935,7 @@ static int64_t avalon_scanhash(struct thr_info *thr) * * Any patch will be great. */ - scanret = hash_count * 2; -out: - avalon_free_work(thr, avalon->works); - avalon->queued = 0; - return scanret; + return hash_count * 2; } static struct api_data *avalon_api_stats(struct cgpu_info *cgpu) diff --git a/driver-avalon.h b/driver-avalon.h index d4fb9d9c..f8607409 100644 --- a/driver-avalon.h +++ b/driver-avalon.h @@ -96,10 +96,6 @@ struct avalon_info { int no_matching_work; int matching_work[AVALON_DEFAULT_MINER_NUM]; - struct work *bulk0[AVALON_DEFAULT_MINER_NUM]; - struct work *bulk1[AVALON_DEFAULT_MINER_NUM]; - struct work *bulk2[AVALON_DEFAULT_MINER_NUM]; - struct work *bulk3[AVALON_DEFAULT_MINER_NUM]; int frequency; };