From 581271b0e9afbc33834dcd5d531895c8d1391bef Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Fri, 14 Jun 2013 14:50:14 +0700 Subject: [PATCH 01/31] add cgminer driver file as-is --- cgminer/driver-klondike.c | 124 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 cgminer/driver-klondike.c diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c new file mode 100644 index 00000000..39c55d3b --- /dev/null +++ b/cgminer/driver-klondike.c @@ -0,0 +1,124 @@ +/* + * Copyright 2013 Andrew Smith + * Copyright 2013 Con Kolivas + * Copyright 2013 Chris Savery + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. See COPYING for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" + +#ifdef WIN32 +#include +#endif + +#include "compat.h" +#include "miner.h" +#include "usbutils.h" + +#define K1 "K1" +#define K16 "K16" +#define K64 "K64" + +#define REPLY_BUFSIZE 64 + +struct device_drv klondike_drv; + +struct klondike_id { + char id[8]; + uint8_t version; + uint32_t serial; + char product[16]; +}; + +struct klondike_status { + +}; + +struct kondike_cfg { + +}; + + +static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) +{ + struct cgpu_info *klninfo = calloc(1, sizeof(*klninfo)); + char replybuf[REPLY_BUFSIZE]; + char devpath[20]; + int attempts = 0; + int sent, recd, err; + + if (unlikely(!klninfo)) + quit(1, "Failed to calloc klninfo in klondike_detect_one"); + + klninfo->drv = &klondike_drv; + klninfo->deven = DEV_ENABLED; + klninfo->threads = 1; + + if (usb_init(klninfo, dev, found)) { + + sprintf(devpath, "%d:%d", (int)(klninfo->usbinfo.bus_number), (int)(klninfo->usbinfo.device_address)); + while(attempts++ < 2) { + + err = usb_write(klninfo, "I", 2, &sent, C_REQUESTIDENTIFY); + if (err < 0 || sent != 2) { + applog(LOG_ERR, "%s detect (%s) send identify request failed (%d:%d)", klninfo->drv->dname, devpath, sent, err); + break; + } + + err = usb_read(klninfo, replybuf, sizeof(replybuf), &recd, C_GETIDENTIFY); + if (err < 0) { + applog(LOG_ERR, "%s detect (%s) error identify reply (%d:%d)", klninfo->drv->dname, devpath, recd, err); + } else if (recd < 1) { + applog(LOG_ERR, "%s detect (%s) empty identify reply (%d)", klninfo->drv->dname, devpath, recd); + } else if (replybuf[0] == 'I' && replybuf[1] == 0) { + applog(LOG_DEBUG, "%s (%s) identified as: '%s'", klninfo->drv->dname, devpath, klninfo->drv->name); + + // do something with id info + + update_usb_stats(klninfo); + return true; + } + } + usb_uninit(klninfo); + } + free(klninfo); + return false; +} + +static void klondike_detect(void) +{ + usb_detect(&klondike_drv, klondike_detect_one); +} + + +struct device_drv klondike_drv = { + .drv_id = DRIVER_KLONDIKE, + .dname = "Klondike", + .name = K16, + .drv_detect = klondike_detect, + .get_api_stats = klondike_api_stats, + .get_statline_before = get_klondike_statline_before, + .get_stats = klondike_get_stats, + .identify_device = klondike_identify, + .thread_prepare = klondike_thread_prepare, + .thread_init = klondike_thread_init, + .hash_work = hash_queued_work, + .scanwork = klondike_scanwork, + .queue_full = klondike_queue_full, + .flush_work = klondike_flush_work, + .thread_shutdown = klondike_shutdown, + .thread_enable = klondike_thread_enable +}; From 2b3abd1b5dc4f2cabb43da5ce80300aaefc5ae83 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Sat, 15 Jun 2013 14:58:07 +0700 Subject: [PATCH 02/31] update klondike driver --- cgminer/driver-klondike.c | 124 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 119 insertions(+), 5 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 39c55d3b..29634ca9 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -36,22 +36,35 @@ struct device_drv klondike_drv; +struct klondike_info { + bool shutdown; +}; + struct klondike_id { - char id[8]; uint8_t version; uint32_t serial; - char product[16]; + char product[8]; }; struct klondike_status { - + uint8_t state; + uint8_t chipcount; + uint8_t slavecount; + uint8_t workqc; + uint8_t workid; + uint8_t temp; + uint8_t fanspeed; + uint16_t hashcount; + uint16_t errorcount; }; struct kondike_cfg { - + uint16_t hashclock; + uint8_t temptarget; + uint8_t tempcritical; + uint8_t fantarget; }; - static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *klninfo = calloc(1, sizeof(*klninfo)); @@ -103,6 +116,107 @@ static void klondike_detect(void) usb_detect(&klondike_drv, klondike_detect_one); } +static void klondike_identify(struct cgpu_info *klninfo) +{ + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + +} + +static bool klondike_thread_prepare(struct thr_info *thr) +{ + struct cgpu_info *klninfo = thr->cgpu; + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + + return true; +} + +static bool klondike_thread_init(struct thr_info *thr) +{ + struct cgpu_info *klninfo = thr->cgpu; + + if (klninfo->usbinfo.nodev) + return false; + + //klondike_initialise(klninfo); + + return true; +} + +static void klondike_flush_work(struct cgpu_info *klninfo) +{ + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + +} + +static void klondike_shutdown(struct thr_info *thr) +{ + struct cgpu_info *klninfo = thr->cgpu; + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + + klondike_flush_work(klninfo); + k_info->shutdown = true; +} + +static void klondike_thread_enable(struct thr_info *thr) +{ + struct cgpu_info *klninfo = thr->cgpu; + + if (klninfo->usbinfo.nodev) + return; + + //klondike_initialise(bflsc); +} + +static bool klondike_send_work(struct cgpu_info *klninfo, int dev, struct work *work) +{ + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + + // Device is gone + if (klninfo->usbinfo.nodev) + return false; + +} + +static bool klondike_queue_full(struct cgpu_info *klninfo) +{ + struct klondike_info *sc_info = (struct klondike_info *)(klninfo->device_file); + + +} + +static int64_t klondike_scanwork(struct thr_info *thr) +{ + struct cgpu_info *klninfo = thr->cgpu; + struct klondike_info *sc_info = (struct klondike_info *)(klninfo->device_file); + + // Device is gone + if (klninfo->usbinfo.nodev) + return -1; + +} + +static bool klondike_get_stats(struct cgpu_info *klninfo) +{ + struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + bool allok = true; + int i; + + // Device is gone + if (klninfo->usbinfo.nodev) + return false; + + return allok; +} + +static void get_klondike_statline_before(char *buf, struct cgpu_info *klninfo) +{ + +} + +static struct api_data *klondike_api_stats(struct cgpu_info *klninfo) +{ + +} struct device_drv klondike_drv = { .drv_id = DRIVER_KLONDIKE, From 158f3273fee1f50f8f752f0a4e0a34c865bdf7d5 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 2 Jul 2013 20:40:54 +0700 Subject: [PATCH 03/31] update firmware and driver, create new cgminer fork --- cgminer/driver-klondike.c | 458 ++++++++++++++++++++++++++++++-------- 1 file changed, 370 insertions(+), 88 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 29634ca9..867887a4 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "config.h" @@ -28,25 +29,29 @@ #include "miner.h" #include "usbutils.h" +#define KLN "KLN" #define K1 "K1" #define K16 "K16" #define K64 "K64" -#define REPLY_BUFSIZE 64 +#define MIDSTATE_BYTES 32 +#define MERKLE_OFFSET 64 +#define MERKLE_BYTES 12 -struct device_drv klondike_drv; +#define REPLY_BUFSIZE 32 // adequate for all types of replies +#define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss +#define REPLY_WAIT_TIME 100 // time to wait for a cmd polling it's reply +#define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware -struct klondike_info { - bool shutdown; -}; +struct device_drv klondike_drv; -struct klondike_id { +typedef struct klondike_id { uint8_t version; + uint8_t product[7]; uint32_t serial; - char product[8]; -}; +} IDENTITY; -struct klondike_status { +typedef struct klondike_status { uint8_t state; uint8_t chipcount; uint8_t slavecount; @@ -54,60 +59,195 @@ struct klondike_status { uint8_t workid; uint8_t temp; uint8_t fanspeed; + uint8_t errorcount; uint16_t hashcount; - uint16_t errorcount; -}; - -struct kondike_cfg { + uint16_t maxcount; +} WORKSTATUS; + +typedef struct _worktask { + uint16_t pad1; + uint8_t pad2; + uint8_t workid; + uint32_t midstate[8]; + uint32_t merkle[3]; +} WORKTASK; + +typedef struct _workresult { + uint16_t pad; + uint8_t device; + uint8_t workid; + uint32_t nonce; +} WORKRESULT; + +typedef struct kondike_cfg { uint16_t hashclock; uint8_t temptarget; uint8_t tempcritical; uint8_t fantarget; + uint8_t pad; +} WORKCFG; + +typedef struct device_info { + uint32_t noncecount; + uint32_t nextworkid; + uint16_t lasthashcount; + uint64_t totalhashcount; +} DEVINFO; + +struct klondike_info { + bool shutdown; + pthread_rwlock_t stat_lock; + struct thr_info replies_thr; + WORKSTATUS *status; + DEVINFO *devinfo; + WORKCFG *cfg; + char *replies; + int nextreply; }; -static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) +IDENTITY KlondikeID; + +static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, int datalen, void *data) { - struct cgpu_info *klninfo = calloc(1, sizeof(*klninfo)); + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + char outbuf[64]; + int retries = 10; + int chkreply = klninfo->nextreply; + int sent, err; + + if (klncgpu->usbinfo.nodev) + return NULL; + + outbuf[0] = Cmd; + outbuf[1] = device; + memcpy(outbuf+2, data, datalen); + err = usb_write(klncgpu, outbuf, 2+datalen, &sent, C_REQUESTRESULTS); + if (err < 0 || sent != 2+datalen) { + applog(LOG_ERR, "%s (%s) Cmd:%c Dev:%d, write failed (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, Cmd, device, sent, err); + } + while(retries-- > 0) { + nmsleep(REPLY_WAIT_TIME); + while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd) { + if(++chkreply == MAX_REPLY_COUNT) + chkreply = 0; + if(chkreply == klninfo->nextreply) + break; + } + if(chkreply == klninfo->nextreply) + continue; + *(klninfo->replies + chkreply*REPLY_BUFSIZE) = '!'; // mark to prevent re-use + return klninfo->replies + chkreply*REPLY_BUFSIZE + 1; + } + return NULL; +} + +static bool klondike_get_stats(struct cgpu_info *klncgpu) +{ + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); char replybuf[REPLY_BUFSIZE]; char devpath[20]; - int attempts = 0; + bool allok = false; int sent, recd, err; + int slaves, dev; - if (unlikely(!klninfo)) - quit(1, "Failed to calloc klninfo in klondike_detect_one"); + if (klncgpu->usbinfo.nodev) + return false; + + char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); + if(reply != NULL && reply[0] == 'S' && reply[1] == 0) { + + // todo: detect slavecount change and realloc space + slaves = ((WORKSTATUS *)(reply+2))->slavecount; + if(klninfo->status == NULL) { + applog(LOG_DEBUG, "Klondike initializing status data"); + // alloc space for status, devinfo and cfg for master and slaves + klninfo->status = calloc(slaves+1, sizeof(WORKSTATUS)); + if (unlikely(!klninfo->status)) + quit(1, "Failed to calloc status array in klondke_get_stats"); + klninfo->devinfo = calloc(slaves+1, sizeof(DEVINFO)); + if (unlikely(!klninfo->devinfo)) + quit(1, "Failed to calloc devinfo array in klondke_get_stats"); + klninfo->cfg = calloc(slaves+1, sizeof(WORKCFG)); + if (unlikely(!klninfo->cfg)) + quit(1, "Failed to calloc cfg array in klondke_get_stats"); + + // where does saved user cfg info come from? + // todo: set user cfg to devices + } + applog(LOG_DEBUG, "Klondike updating device status"); - klninfo->drv = &klondike_drv; - klninfo->deven = DEV_ENABLED; - klninfo->threads = 1; + // device 0 is master and must exist + wr_lock(&(klninfo->stat_lock)); + klninfo->status[0] = *(WORKSTATUS *)(reply+2); - if (usb_init(klninfo, dev, found)) { + // loop thru slaves and get status for each + for(dev = 1; dev < slaves; dev++) { + + + } + wr_unlock(&(klninfo->stat_lock)); + allok = true; + } + return allok; +} + +static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) +{ + struct cgpu_info *klncgpu = calloc(1, sizeof(*klncgpu)); + struct klondike_info *klninfo = NULL; + + int attempts = 0; + + if (unlikely(!klncgpu)) + quit(1, "Failed to calloc klncgpu in klondike_detect_one"); - sprintf(devpath, "%d:%d", (int)(klninfo->usbinfo.bus_number), (int)(klninfo->usbinfo.device_address)); - while(attempts++ < 2) { + klncgpu->drv = &klondike_drv; + klncgpu->deven = DEV_ENABLED; + klncgpu->threads = 1; + + klninfo = calloc(1, sizeof(*klninfo)); + if (unlikely(!klninfo)) + quit(1, "Failed to calloc klninfo in klondke_detect_one"); + // TODO: fix ... everywhere ... + klncgpu->device_data = (FILE *)klninfo; + + klninfo->replies = calloc(MAX_REPLY_COUNT, REPLY_BUFSIZE); + if (unlikely(!klninfo->replies)) + quit(1, "Failed to calloc replies buffer in klondke_detect_one"); + klninfo->nextreply = 0; + + if (usb_init(klncgpu, dev, found)) { + + while(attempts++ < 3) { + char devpath[20], reply[32]; + int sent, recd, err; - err = usb_write(klninfo, "I", 2, &sent, C_REQUESTIDENTIFY); + sprintf(devpath, "%d:%d", (int)(klncgpu->usbinfo.bus_number), (int)(klncgpu->usbinfo.device_address)); + err = usb_write(klncgpu, "I", 2, &sent, C_REQUESTRESULTS); if (err < 0 || sent != 2) { - applog(LOG_ERR, "%s detect (%s) send identify request failed (%d:%d)", klninfo->drv->dname, devpath, sent, err); - break; + applog(LOG_ERR, "%s (%s) detect write failed (%d:%d)", klncgpu->drv->dname, devpath, sent, err); } - - err = usb_read(klninfo, replybuf, sizeof(replybuf), &recd, C_GETIDENTIFY); + nmsleep(REPLY_WAIT_TIME*10); + err = usb_read(klncgpu, reply, sizeof(IDENTITY)+2, &recd, C_GETRESULTS); if (err < 0) { - applog(LOG_ERR, "%s detect (%s) error identify reply (%d:%d)", klninfo->drv->dname, devpath, recd, err); + applog(LOG_ERR, "%s (%s) detect read failed (%d:%d)", klncgpu->drv->dname, devpath, recd, err); } else if (recd < 1) { - applog(LOG_ERR, "%s detect (%s) empty identify reply (%d)", klninfo->drv->dname, devpath, recd); - } else if (replybuf[0] == 'I' && replybuf[1] == 0) { - applog(LOG_DEBUG, "%s (%s) identified as: '%s'", klninfo->drv->dname, devpath, klninfo->drv->name); - - // do something with id info - - update_usb_stats(klninfo); + applog(LOG_ERR, "%s (%s) detect empty reply (%d)", klncgpu->drv->dname, devpath, recd); + } else if(reply[0] == 'I' && reply[1] == 0) { + + applog(LOG_DEBUG, "%s (%s) detect successful", klncgpu->drv->dname, devpath); + KlondikeID = *(IDENTITY *)(&reply[2]); + klncgpu->device_path = strdup(devpath); + update_usb_stats(klncgpu); + if(!add_cgpu(klncgpu)) + break; + applog(LOG_DEBUG, "Klondike cgpu added"); return true; } } - usb_uninit(klninfo); + usb_uninit(klncgpu); } - free(klninfo); + free(klncgpu); return false; } @@ -116,112 +256,254 @@ static void klondike_detect(void) usb_detect(&klondike_drv, klondike_detect_one); } -static void klondike_identify(struct cgpu_info *klninfo) +static void klondike_identify(struct cgpu_info *klncgpu) { - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + SendCmdGetReply(klncgpu, 'I', 0, 0, NULL); +} +static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) +{ + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct work *work, *tmp; + + applog(LOG_DEBUG, "Klondike FOUND NONCE (x%08x)", result->nonce); + HASH_ITER(hh, klncgpu->queued_work, work, tmp) { + if (work->queued && (work->subid == (result->device*256 + result->workid))) { + // devflag is used to flag stale work + work->devflag = true; + + wr_lock(&(klninfo->stat_lock)); + klninfo->devinfo[result->device].noncecount++; + wr_unlock(&(klninfo->stat_lock)); + + result->nonce = le32toh(result->nonce - 0xC0); + applog(LOG_DEBUG, "Klondike SUBMIT NONCE (x%08x)", result->nonce); + submit_nonce(klncgpu->thr[0], work, result->nonce); + } + return; + } + + applog(LOG_ERR, "%s%i:%d failed to find nonce work (x%08x) - can't be processed - ignored", + klncgpu->drv->name, klncgpu->device_id, result->device, result->nonce); + //inc_hw_errors(klncgpu->thr[0]); } -static bool klondike_thread_prepare(struct thr_info *thr) +// thread to keep looking for replies +static void *klondike_get_replies(void *userdata) { - struct cgpu_info *klninfo = thr->cgpu; - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + struct cgpu_info *klncgpu = (struct cgpu_info *)userdata; + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + char *replybuf; + int err, recd; + + applog(LOG_DEBUG, "Klondike listening for replies"); + + while (klninfo->shutdown == false) { + if (klncgpu->usbinfo.nodev) + return NULL; + + replybuf = klninfo->replies + klninfo->nextreply * REPLY_BUFSIZE; + replybuf[0] = 0; + + err = usb_read(klncgpu, replybuf+1, REPLY_BUFSIZE-1, &recd, C_GETRESULTS); + if (err < 0 && err != -7) + applog(LOG_DEBUG, "%s (%s) error reply (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, recd, err); + if (recd < 1) + continue; + else { + if(opt_log_level <= LOG_DEBUG) { + char *hexdata = bin2hex(replybuf+1, recd); + applog(LOG_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); + free(hexdata); + } + if(++klninfo->nextreply == MAX_REPLY_COUNT) + klninfo->nextreply = 0; + + replybuf[0] = replybuf[1]; + if(replybuf[0] == '=') + klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); + } + + } + return NULL; +} +static bool klondike_thread_prepare(struct thr_info *thr) +{ + struct cgpu_info *klncgpu = thr->cgpu; + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct timeval now; + + if (thr_info_create(&(klninfo->replies_thr), NULL, klondike_get_replies, (void *)klncgpu)) { + applog(LOG_ERR, "%s%i: thread create failed", klncgpu->drv->name, klncgpu->device_id); + return false; + } + pthread_detach(klninfo->replies_thr.pth); + + // init status data structures + nmsleep(500); + klondike_get_stats(klncgpu); + return true; } +static void klondike_flush_work(struct cgpu_info *klncgpu) +{ + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + int dev; + + applog(LOG_DEBUG, "Klondike flushing work work"); + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); + if(reply != NULL && reply[0] == 'A' && reply[1] == dev) { + wr_lock(&(klninfo->stat_lock)); + klninfo->status[dev] = *(WORKSTATUS *)(reply+2); + wr_unlock(&(klninfo->stat_lock)); + } + } +} + static bool klondike_thread_init(struct thr_info *thr) { - struct cgpu_info *klninfo = thr->cgpu; + struct cgpu_info *klncgpu = thr->cgpu; - if (klninfo->usbinfo.nodev) + if (klncgpu->usbinfo.nodev) return false; - //klondike_initialise(klninfo); + klondike_flush_work(klncgpu); return true; } -static void klondike_flush_work(struct cgpu_info *klninfo) -{ - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); - -} - static void klondike_shutdown(struct thr_info *thr) { - struct cgpu_info *klninfo = thr->cgpu; - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + struct cgpu_info *klncgpu = thr->cgpu; + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - klondike_flush_work(klninfo); - k_info->shutdown = true; + klondike_flush_work(klncgpu); + klninfo->shutdown = true; } static void klondike_thread_enable(struct thr_info *thr) { - struct cgpu_info *klninfo = thr->cgpu; + struct cgpu_info *klncgpu = thr->cgpu; - if (klninfo->usbinfo.nodev) + if (klncgpu->usbinfo.nodev) return; - //klondike_initialise(bflsc); + klondike_flush_work(klncgpu); } -static bool klondike_send_work(struct cgpu_info *klninfo, int dev, struct work *work) +static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work *work) { - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + WORKTASK data; - // Device is gone - if (klninfo->usbinfo.nodev) + if (klncgpu->usbinfo.nodev) return false; + memcpy(data.midstate, work->midstate, MIDSTATE_BYTES); + memcpy(data.merkle, work->data + MERKLE_OFFSET, MERKLE_BYTES); + data.workid = (uint8_t)(klninfo->devinfo[dev].nextworkid++); + work->subid = dev*256 + data.workid; + + applog(LOG_DEBUG, "Klondike sending work (%d:x%02x)", dev, data.workid); + char *reply = SendCmdGetReply(klncgpu, 'W', dev, sizeof(data)-3, &data.workid); + if(reply != NULL && reply[0] == 'W' && reply[1] == dev) { + wr_lock(&(klninfo->stat_lock)); + klninfo->status[dev] = *(WORKSTATUS *)(reply+2); + wr_unlock(&(klninfo->stat_lock)); + return true; + } + return false; } -static bool klondike_queue_full(struct cgpu_info *klninfo) +static bool klondike_queue_full(struct cgpu_info *klncgpu) { - struct klondike_info *sc_info = (struct klondike_info *)(klninfo->device_file); - + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct work *work = NULL; + int dev, queued; + for(queued = 0; queued < MAX_WORK_COUNT-1; queued++) + for(dev = 0; dev <= klninfo->status->slavecount; dev++) + if (klninfo->status[dev].workqc <= queued) { + if (!work) + work = get_queued(klncgpu); + if (unlikely(!work)) + return false; + if (klondike_send_work(klncgpu, dev, work)) { + work = NULL; + break; + } + } + + return true; } static int64_t klondike_scanwork(struct thr_info *thr) { - struct cgpu_info *klninfo = thr->cgpu; - struct klondike_info *sc_info = (struct klondike_info *)(klninfo->device_file); - - // Device is gone - if (klninfo->usbinfo.nodev) + struct cgpu_info *klncgpu = thr->cgpu; + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + int64_t newhashcount = 0; + int dev; + + if (klncgpu->usbinfo.nodev) return -1; - + restart_wait(500); + if (klninfo->status != NULL) { + rd_lock(&(klninfo->stat_lock)); + for(dev = 0; dev <= klninfo->status->slavecount; dev++) { + uint64_t newhashdev = 0; + if(klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) + newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped + newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; + klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; + newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; + } + rd_unlock(&(klninfo->stat_lock)); + } + return newhashcount; } -static bool klondike_get_stats(struct cgpu_info *klninfo) +static double convertKlnTemp(uint8_t temp) { - struct klondike_info *k_info = (struct klondike_info *)(klninfo->device_file); - bool allok = true; - int i; - - // Device is gone - if (klninfo->usbinfo.nodev) - return false; - - return allok; + return (double)1/((double)1/(25+273.15) + log((double)temp*1000/(256-temp)/2200)/3987) - 273.15; } -static void get_klondike_statline_before(char *buf, struct cgpu_info *klninfo) +static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) { - + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + uint8_t temp = 0xFF; + int dev; + + rd_lock(&(klninfo->stat_lock)); + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + if (klninfo->status[dev].temp < temp) + temp = klninfo->status[dev].temp; + } + rd_unlock(&(klninfo->stat_lock)); + + tailsprintf(buf, " %3.0fC 1.2V | ", convertKlnTemp(temp)); } -static struct api_data *klondike_api_stats(struct cgpu_info *klninfo) +static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) { - + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct api_data *root = NULL; + + rd_lock(&(klninfo->stat_lock)); + // todo: convert temp and make correct type float + //root = api_add_temp(root, "Temp", &(klninfo->status->temp), true); + // todo: convert hashclock value to MHz and correct type double + //root = api_add_freq(root, "Clock", &(klninfo->cfg->hashclock), true); + rd_unlock(&(klninfo->stat_lock)); + } struct device_drv klondike_drv = { .drv_id = DRIVER_KLONDIKE, .dname = "Klondike", - .name = K16, + .name = KLN, .drv_detect = klondike_detect, .get_api_stats = klondike_api_stats, .get_statline_before = get_klondike_statline_before, From 3cbb2814069a9802b7367e367ad52663110612b1 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Tue, 2 Jul 2013 21:43:38 +0700 Subject: [PATCH 04/31] updated cgminer driver for 3.3.1 --- cgminer/driver-klondike.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 867887a4..9168ec80 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -193,7 +193,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { - struct cgpu_info *klncgpu = calloc(1, sizeof(*klncgpu)); + struct cgpu_info *klncgpu = usb_alloc_cgpu(&klondike_drv, 1); struct klondike_info *klninfo = NULL; int attempts = 0; @@ -201,10 +201,6 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic if (unlikely(!klncgpu)) quit(1, "Failed to calloc klncgpu in klondike_detect_one"); - klncgpu->drv = &klondike_drv; - klncgpu->deven = DEV_ENABLED; - klncgpu->threads = 1; - klninfo = calloc(1, sizeof(*klninfo)); if (unlikely(!klninfo)) quit(1, "Failed to calloc klninfo in klondke_detect_one"); @@ -278,7 +274,8 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) result->nonce = le32toh(result->nonce - 0xC0); applog(LOG_DEBUG, "Klondike SUBMIT NONCE (x%08x)", result->nonce); - submit_nonce(klncgpu->thr[0], work, result->nonce); + if(submit_nonce(klncgpu->thr[0], work, result->nonce)) + work_completed(klncgpu, work); } return; } From 95d102eb5bc6b2347ee20b37e09e7fb7c2698310 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Fri, 5 Jul 2013 00:08:13 +0700 Subject: [PATCH 05/31] update firmware & utils --- cgminer/driver-klondike.c | 98 ++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 9168ec80..62eed0fa 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -38,9 +38,10 @@ #define MERKLE_OFFSET 64 #define MERKLE_BYTES 12 -#define REPLY_BUFSIZE 32 // adequate for all types of replies +#define REPLY_SIZE 15 // adequate for all types of replies +#define REPLY_BUFSIZE 16 // reply + 1 byte to mark used #define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss -#define REPLY_WAIT_TIME 100 // time to wait for a cmd polling it's reply +#define REPLY_WAIT_TIME 100 // poll interval for a cmd waiting it's reply #define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware struct device_drv klondike_drv; @@ -127,7 +128,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in } while(retries-- > 0) { nmsleep(REPLY_WAIT_TIME); - while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd) { + while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd || *(klninfo->replies + chkreply*REPLY_BUFSIZE + 2) != device) { if(++chkreply == MAX_REPLY_COUNT) chkreply = 0; if(chkreply == klninfo->nextreply) @@ -154,7 +155,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) return false; char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); - if(reply != NULL && reply[0] == 'S' && reply[1] == 0) { + if(reply != NULL) { // todo: detect slavecount change and realloc space slaves = ((WORKSTATUS *)(reply+2))->slavecount; @@ -174,16 +175,17 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) // where does saved user cfg info come from? // todo: set user cfg to devices } - applog(LOG_DEBUG, "Klondike updating device status"); + applog(LOG_DEBUG, "Klondike updating status"); // device 0 is master and must exist wr_lock(&(klninfo->stat_lock)); klninfo->status[0] = *(WORKSTATUS *)(reply+2); // loop thru slaves and get status for each - for(dev = 1; dev < slaves; dev++) { - - + for(dev = 1; dev <= slaves; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); + if(reply != NULL) + klninfo->status[dev] = *(WORKSTATUS *)(reply+2); } wr_unlock(&(klninfo->stat_lock)); allok = true; @@ -196,8 +198,6 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic struct cgpu_info *klncgpu = usb_alloc_cgpu(&klondike_drv, 1); struct klondike_info *klninfo = NULL; - int attempts = 0; - if (unlikely(!klncgpu)) quit(1, "Failed to calloc klncgpu in klondike_detect_one"); @@ -213,9 +213,9 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic klninfo->nextreply = 0; if (usb_init(klncgpu, dev, found)) { - + int attempts = 0; while(attempts++ < 3) { - char devpath[20], reply[32]; + char devpath[20], reply[REPLY_SIZE]; int sent, recd, err; sprintf(devpath, "%d:%d", (int)(klncgpu->usbinfo.bus_number), (int)(klncgpu->usbinfo.device_address)); @@ -224,7 +224,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic applog(LOG_ERR, "%s (%s) detect write failed (%d:%d)", klncgpu->drv->dname, devpath, sent, err); } nmsleep(REPLY_WAIT_TIME*10); - err = usb_read(klncgpu, reply, sizeof(IDENTITY)+2, &recd, C_GETRESULTS); + err = usb_read(klncgpu, reply, REPLY_SIZE, &recd, C_GETRESULTS); if (err < 0) { applog(LOG_ERR, "%s (%s) detect read failed (%d:%d)", klncgpu->drv->dname, devpath, recd, err); } else if (recd < 1) { @@ -254,7 +254,7 @@ static void klondike_detect(void) static void klondike_identify(struct cgpu_info *klncgpu) { - SendCmdGetReply(klncgpu, 'I', 0, 0, NULL); + //SendCmdGetReply(klncgpu, 'I', 0, 0, NULL); } static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) @@ -262,26 +262,23 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct work *work, *tmp; - applog(LOG_DEBUG, "Klondike FOUND NONCE (x%08x)", result->nonce); + applog(LOG_DEBUG, "Klondike FOUND NONCE (%02x:%08x)", result->workid, result->nonce); HASH_ITER(hh, klncgpu->queued_work, work, tmp) { if (work->queued && (work->subid == (result->device*256 + result->workid))) { - // devflag is used to flag stale work - work->devflag = true; wr_lock(&(klninfo->stat_lock)); klninfo->devinfo[result->device].noncecount++; wr_unlock(&(klninfo->stat_lock)); result->nonce = le32toh(result->nonce - 0xC0); - applog(LOG_DEBUG, "Klondike SUBMIT NONCE (x%08x)", result->nonce); - if(submit_nonce(klncgpu->thr[0], work, result->nonce)) - work_completed(klncgpu, work); - } + applog(LOG_DEBUG, "Klondike SUBMIT NONCE (%02x:%08x)", result->workid, result->nonce); + submit_nonce(klncgpu->thr[0], work, result->nonce); return; + } } - applog(LOG_ERR, "%s%i:%d failed to find nonce work (x%08x) - can't be processed - ignored", - klncgpu->drv->name, klncgpu->device_id, result->device, result->nonce); + applog(LOG_ERR, "%s%i:%d failed to find nonce work (%02x:%08x) - can't be processed - ignored", + klncgpu->drv->name, klncgpu->device_id, result->device, result->workid, result->nonce); //inc_hw_errors(klncgpu->thr[0]); } @@ -302,12 +299,8 @@ static void *klondike_get_replies(void *userdata) replybuf = klninfo->replies + klninfo->nextreply * REPLY_BUFSIZE; replybuf[0] = 0; - err = usb_read(klncgpu, replybuf+1, REPLY_BUFSIZE-1, &recd, C_GETRESULTS); - if (err < 0 && err != -7) - applog(LOG_DEBUG, "%s (%s) error reply (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, recd, err); - if (recd < 1) - continue; - else { + err = usb_read(klncgpu, replybuf+1, REPLY_SIZE, &recd, C_GETRESULTS); + if (recd == REPLY_SIZE) { if(opt_log_level <= LOG_DEBUG) { char *hexdata = bin2hex(replybuf+1, recd); applog(LOG_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); @@ -319,8 +312,7 @@ static void *klondike_get_replies(void *userdata) replybuf[0] = replybuf[1]; if(replybuf[0] == '=') klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); - } - + } } return NULL; } @@ -349,10 +341,13 @@ static void klondike_flush_work(struct cgpu_info *klncgpu) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int dev; + if(klninfo->status == NULL) + return; + applog(LOG_DEBUG, "Klondike flushing work work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); - if(reply != NULL && reply[0] == 'A' && reply[1] == dev) { + if(reply != NULL) { wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); @@ -401,12 +396,18 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * memcpy(data.midstate, work->midstate, MIDSTATE_BYTES); memcpy(data.merkle, work->data + MERKLE_OFFSET, MERKLE_BYTES); - data.workid = (uint8_t)(klninfo->devinfo[dev].nextworkid++); + data.workid = (uint8_t)(klninfo->devinfo[dev].nextworkid++ & 0xFF); work->subid = dev*256 + data.workid; - applog(LOG_DEBUG, "Klondike sending work (%d:x%02x)", dev, data.workid); + if(opt_log_level <= LOG_DEBUG) { + char *hexdata = bin2hex(&data.workid, sizeof(data)-3); + applog(LOG_DEBUG, "WORKDATA: %s", hexdata); + free(hexdata); + } + + applog(LOG_DEBUG, "Klondike sending work (%d:%02x)", dev, data.workid); char *reply = SendCmdGetReply(klncgpu, 'W', dev, sizeof(data)-3, &data.workid); - if(reply != NULL && reply[0] == 'W' && reply[1] == dev) { + if(reply != NULL) { wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); @@ -446,16 +447,21 @@ static int64_t klondike_scanwork(struct thr_info *thr) if (klncgpu->usbinfo.nodev) return -1; - restart_wait(500); + + restart_wait(200); if (klninfo->status != NULL) { rd_lock(&(klninfo->stat_lock)); for(dev = 0; dev <= klninfo->status->slavecount; dev++) { uint64_t newhashdev = 0; - if(klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) + if(klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) // todo: chg this to check workid for wrapped instead newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; + + // discard old work + + // work_completed(klncgpu, work); } rd_unlock(&(klninfo->stat_lock)); } @@ -487,12 +493,20 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct api_data *root = NULL; - + char buf[12]; + int dev; + rd_lock(&(klninfo->stat_lock)); - // todo: convert temp and make correct type float - //root = api_add_temp(root, "Temp", &(klninfo->status->temp), true); - // todo: convert hashclock value to MHz and correct type double - //root = api_add_freq(root, "Clock", &(klninfo->cfg->hashclock), true); + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + + float ftemp = convertKlnTemp(klninfo->status[dev].temp); + sprintf(buf, "Temp%d", dev); + root = api_add_temp(root, buf, &ftemp, true); + + double dclk = (double)klninfo->cfg[dev].hashclock / 2; + sprintf(buf, "Clock%d", dev); + root = api_add_freq(root, buf, &dclk, true); + } rd_unlock(&(klninfo->stat_lock)); } From 9c522a086f7758d4164bb0e75624ada488e364dc Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Sat, 6 Jul 2013 11:00:07 +0700 Subject: [PATCH 06/31] update driver, docs --- cgminer/driver-klondike.c | 62 ++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 62eed0fa..42bab824 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -38,11 +38,12 @@ #define MERKLE_OFFSET 64 #define MERKLE_BYTES 12 -#define REPLY_SIZE 15 // adequate for all types of replies -#define REPLY_BUFSIZE 16 // reply + 1 byte to mark used -#define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss -#define REPLY_WAIT_TIME 100 // poll interval for a cmd waiting it's reply -#define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware +#define REPLY_SIZE 15 // adequate for all types of replies +#define REPLY_BUFSIZE 16 // reply + 1 byte to mark used +#define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss +#define REPLY_WAIT_TIME 100 // poll interval for a cmd waiting it's reply +#define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware +#define TACH_FACTOR 87890 // fan rpm divisor struct device_drv klondike_drv; @@ -141,14 +142,26 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in } return NULL; } +static bool klondike_get_cfgs(struct cgpu_info *klncgpu) +{ + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + int dev; + + if (klncgpu->usbinfo.nodev || klninfo->status == NULL) + return false; + + for(dev = 0; dev <= klninfo->status->slavecount; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'C', dev, 1, ""); + if(reply != NULL) + klninfo->cfg[dev] = *(WORKCFG *)(reply+2); + } + return true; +} static bool klondike_get_stats(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - char replybuf[REPLY_BUFSIZE]; - char devpath[20]; bool allok = false; - int sent, recd, err; int slaves, dev; if (klncgpu->usbinfo.nodev) @@ -384,6 +397,7 @@ static void klondike_thread_enable(struct thr_info *thr) return; klondike_flush_work(klncgpu); + klondike_get_cfgs(klncgpu); } static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work *work) @@ -459,9 +473,8 @@ static int64_t klondike_scanwork(struct thr_info *thr) klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; - // discard old work + // check stats for critical conditions - // work_completed(klncgpu, work); } rd_unlock(&(klninfo->stat_lock)); } @@ -486,29 +499,38 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) } rd_unlock(&(klninfo->stat_lock)); - tailsprintf(buf, " %3.0fC 1.2V | ", convertKlnTemp(temp)); + tailsprintf(buf, " %3.0fC 1.2V | ", convertKlnTemp(temp)); } static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct api_data *root = NULL; - char buf[12]; + char buf[32]; int dev; - + rd_lock(&(klninfo->stat_lock)); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { - float ftemp = convertKlnTemp(klninfo->status[dev].temp); - sprintf(buf, "Temp%d", dev); - root = api_add_temp(root, buf, &ftemp, true); + float fTemp = convertKlnTemp(klninfo->status[dev].temp); + sprintf(buf, "Temp %d", dev); + root = api_add_temp(root, buf, &fTemp, true); + + double dClk = (double)klninfo->cfg[dev].hashclock / 2; + sprintf(buf, "Clock %d", dev); + root = api_add_freq(root, buf, &dClk, true); - double dclk = (double)klninfo->cfg[dev].hashclock / 2; - sprintf(buf, "Clock%d", dev); - root = api_add_freq(root, buf, &dclk, true); + unsigned int iFan = (unsigned int)100 * klninfo->cfg[dev].fantarget / 256; + sprintf(buf, "Fan Percent %d", dev); + root = api_add_int(root, buf, &iFan, true); + + iFan = (unsigned int)TACH_FACTOR / klninfo->status[dev].fanspeed; + sprintf(buf, "Fan RPM %d", dev); + root = api_add_int(root, buf, &iFan, true); } rd_unlock(&(klninfo->stat_lock)); - + + return root; } struct device_drv klondike_drv = { From 6b705d422f58fcc0ea0dc966c1f1fb01116a723e Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Sun, 7 Jul 2013 17:20:00 +0700 Subject: [PATCH 07/31] fixes for 300 MHz, fix K1 parts list --- cgminer/driver-klondike.c | 160 ++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 76 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 42bab824..dcfbadc1 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -142,68 +142,70 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in } return NULL; } -static bool klondike_get_cfgs(struct cgpu_info *klncgpu) + +static bool klondike_init(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - int dev; + int slaves, dev; - if (klncgpu->usbinfo.nodev || klninfo->status == NULL) + char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); + if(reply == NULL) return false; - - for(dev = 0; dev <= klninfo->status->slavecount; dev++) { - char *reply = SendCmdGetReply(klncgpu, 'C', dev, 1, ""); - if(reply != NULL) + + slaves = ((WORKSTATUS *)(reply+2))->slavecount; + if(klninfo->status == NULL) { + applog(LOG_DEBUG, "Klondike initializing data"); + + // alloc space for status, devinfo and cfg for master and slaves + klninfo->status = calloc(slaves+1, sizeof(WORKSTATUS)); + if (unlikely(!klninfo->status)) + quit(1, "Failed to calloc status array in klondke_get_stats"); + klninfo->devinfo = calloc(slaves+1, sizeof(DEVINFO)); + if (unlikely(!klninfo->devinfo)) + quit(1, "Failed to calloc devinfo array in klondke_get_stats"); + klninfo->cfg = calloc(slaves+1, sizeof(WORKCFG)); + if (unlikely(!klninfo->cfg)) + quit(1, "Failed to calloc cfg array in klondke_get_stats"); + } + + // where does saved user cfg info come from? + // todo: set user cfg to devices + for(dev = 0; dev <= slaves; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'C', dev, 2, "\0"); + if(reply != NULL) { klninfo->cfg[dev] = *(WORKCFG *)(reply+2); + applog(LOG_DEBUG, "Klondike config (%d: Clk: %d)", dev, klninfo->cfg[dev].hashclock); + } } - return true; + + SendCmdGetReply(klncgpu, 'E', 0, 1, "1"); + + return true; } - + static bool klondike_get_stats(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - bool allok = false; int slaves, dev; - if (klncgpu->usbinfo.nodev) + if (klncgpu->usbinfo.nodev || klninfo->status == NULL) return false; + + applog(LOG_DEBUG, "Klondike getting status"); + slaves = klninfo->status[0].slavecount; - char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); - if(reply != NULL) { - - // todo: detect slavecount change and realloc space - slaves = ((WORKSTATUS *)(reply+2))->slavecount; - if(klninfo->status == NULL) { - applog(LOG_DEBUG, "Klondike initializing status data"); - // alloc space for status, devinfo and cfg for master and slaves - klninfo->status = calloc(slaves+1, sizeof(WORKSTATUS)); - if (unlikely(!klninfo->status)) - quit(1, "Failed to calloc status array in klondke_get_stats"); - klninfo->devinfo = calloc(slaves+1, sizeof(DEVINFO)); - if (unlikely(!klninfo->devinfo)) - quit(1, "Failed to calloc devinfo array in klondke_get_stats"); - klninfo->cfg = calloc(slaves+1, sizeof(WORKCFG)); - if (unlikely(!klninfo->cfg)) - quit(1, "Failed to calloc cfg array in klondke_get_stats"); - - // where does saved user cfg info come from? - // todo: set user cfg to devices - } - applog(LOG_DEBUG, "Klondike updating status"); - - // device 0 is master and must exist - wr_lock(&(klninfo->stat_lock)); - klninfo->status[0] = *(WORKSTATUS *)(reply+2); - - // loop thru slaves and get status for each - for(dev = 1; dev <= slaves; dev++) { - char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); - if(reply != NULL) - klninfo->status[dev] = *(WORKSTATUS *)(reply+2); - } - wr_unlock(&(klninfo->stat_lock)); - allok = true; + // loop thru devices and get status for each + wr_lock(&(klninfo->stat_lock)); + for(dev = 0; dev <= slaves; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); + if(reply != NULL) + klninfo->status[dev] = *(WORKSTATUS *)(reply+2); } - return allok; + wr_unlock(&(klninfo->stat_lock)); + + // todo: detect slavecount change and realloc space + + return true; } static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) @@ -252,7 +254,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic break; applog(LOG_DEBUG, "Klondike cgpu added"); return true; - } + } } usb_uninit(klncgpu); } @@ -276,6 +278,7 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) struct work *work, *tmp; applog(LOG_DEBUG, "Klondike FOUND NONCE (%02x:%08x)", result->workid, result->nonce); + HASH_ITER(hh, klncgpu->queued_work, work, tmp) { if (work->queued && (work->subid == (result->device*256 + result->workid))) { @@ -290,7 +293,7 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) } } - applog(LOG_ERR, "%s%i:%d failed to find nonce work (%02x:%08x) - can't be processed - ignored", + applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - can't be processed - ignored", klncgpu->drv->name, klncgpu->device_id, result->device, result->workid, result->nonce); //inc_hw_errors(klncgpu->thr[0]); } @@ -330,33 +333,11 @@ static void *klondike_get_replies(void *userdata) return NULL; } -static bool klondike_thread_prepare(struct thr_info *thr) -{ - struct cgpu_info *klncgpu = thr->cgpu; - struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - struct timeval now; - - if (thr_info_create(&(klninfo->replies_thr), NULL, klondike_get_replies, (void *)klncgpu)) { - applog(LOG_ERR, "%s%i: thread create failed", klncgpu->drv->name, klncgpu->device_id); - return false; - } - pthread_detach(klninfo->replies_thr.pth); - - // init status data structures - nmsleep(500); - klondike_get_stats(klncgpu); - - return true; -} - static void klondike_flush_work(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int dev; - - if(klninfo->status == NULL) - return; - + applog(LOG_DEBUG, "Klondike flushing work work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); @@ -368,6 +349,24 @@ static void klondike_flush_work(struct cgpu_info *klncgpu) } } +static bool klondike_thread_prepare(struct thr_info *thr) +{ + struct cgpu_info *klncgpu = thr->cgpu; + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct timeval now; + + if (thr_info_create(&(klninfo->replies_thr), NULL, klondike_get_replies, (void *)klncgpu)) { + applog(LOG_ERR, "%s%i: thread create failed", klncgpu->drv->name, klncgpu->device_id); + return false; + } + pthread_detach(klninfo->replies_thr.pth); + + // let the listening get started + nmsleep(100); + + return klondike_init(klncgpu); +} + static bool klondike_thread_init(struct thr_info *thr) { struct cgpu_info *klncgpu = thr->cgpu; @@ -376,7 +375,7 @@ static bool klondike_thread_init(struct thr_info *thr) return false; klondike_flush_work(klncgpu); - + return true; } @@ -386,6 +385,9 @@ static void klondike_shutdown(struct thr_info *thr) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); klondike_flush_work(klncgpu); + + SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); + klninfo->shutdown = true; } @@ -395,9 +397,9 @@ static void klondike_thread_enable(struct thr_info *thr) if (klncgpu->usbinfo.nodev) return; + + SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); - klondike_flush_work(klncgpu); - klondike_get_cfgs(klncgpu); } static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work *work) @@ -491,12 +493,15 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); uint8_t temp = 0xFF; int dev; + + if(klninfo->status == NULL) + return; rd_lock(&(klninfo->stat_lock)); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { if (klninfo->status[dev].temp < temp) temp = klninfo->status[dev].temp; - } + } rd_unlock(&(klninfo->stat_lock)); tailsprintf(buf, " %3.0fC 1.2V | ", convertKlnTemp(temp)); @@ -509,6 +514,9 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) char buf[32]; int dev; + if(klninfo->status == NULL) + return NULL; + rd_lock(&(klninfo->stat_lock)); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { From fe8bb058a482d5aaacba8ce3e6bd1e289e96cd16 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Mon, 8 Jul 2013 11:04:54 +0700 Subject: [PATCH 08/31] added driver config option support --- cgminer/driver-klondike.c | 54 +++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index dcfbadc1..bd85fcad 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -109,6 +109,17 @@ struct klondike_info { IDENTITY KlondikeID; +static double cvtKlnToC(uint8_t temp) +{ + return (double)1/((double)1/(25+273.15) + log((double)temp*1000/(256-temp)/2200)/3987) - 273.15; +} + +static int cvtCToKln(double deg) +{ + double R = exp((1/(deg+273.15)-1/(273.15+25))*3987)*2200; + return 256*R/(R+1000); +} + static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, int datalen, void *data) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); @@ -167,14 +178,28 @@ static bool klondike_init(struct cgpu_info *klncgpu) if (unlikely(!klninfo->cfg)) quit(1, "Failed to calloc cfg array in klondke_get_stats"); } - - // where does saved user cfg info come from? - // todo: set user cfg to devices + + WORKCFG cfgset = { 0,0,0,0,0 }; // zero init triggers read back only + double temp1, temp2; + int size = 2; + + if(opt_klondike_options != NULL) { // boundaries are checked by device, with valid values returned + sscanf(opt_klondike_options, "%hu,%lf,%lf,%hhu", &cfgset.hashclock, &temp1, &temp2, &cfgset.fantarget); + cfgset.temptarget = cvtCToKln(temp1); + cfgset.tempcritical = cvtCToKln(temp2); + cfgset.fantarget = (int)256*cfgset.fantarget/100; + size = sizeof(cfgset); + } + for(dev = 0; dev <= slaves; dev++) { - char *reply = SendCmdGetReply(klncgpu, 'C', dev, 2, "\0"); + char *reply = SendCmdGetReply(klncgpu, 'C', dev, size, &cfgset); if(reply != NULL) { klninfo->cfg[dev] = *(WORKCFG *)(reply+2); - applog(LOG_DEBUG, "Klondike config (%d: Clk: %d)", dev, klninfo->cfg[dev].hashclock); + applog(LOG_NOTICE, "Klondike config (%d: Clk: %d, T:%.0lf, C:%.0lf, F:%d)", + dev, klninfo->cfg[dev].hashclock, + cvtKlnToC(klninfo->cfg[dev].temptarget), + cvtKlnToC(klninfo->cfg[dev].tempcritical), + (int)100*klninfo->cfg[dev].fantarget/256); } } @@ -384,9 +409,9 @@ static void klondike_shutdown(struct thr_info *thr) struct cgpu_info *klncgpu = thr->cgpu; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - klondike_flush_work(klncgpu); + //SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); - SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); + klondike_flush_work(klncgpu); klninfo->shutdown = true; } @@ -405,6 +430,7 @@ static void klondike_thread_enable(struct thr_info *thr) static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work *work) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct work *tmp; WORKTASK data; if (klncgpu->usbinfo.nodev) @@ -427,6 +453,12 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); + + // remove old work + HASH_ITER(hh, klncgpu->queued_work, work, tmp) { + if (work->queued && (work->subid == (dev*256 + data.workid-2*MAX_WORK_COUNT))) + work_completed(klncgpu, work); + } return true; } return false; @@ -483,10 +515,6 @@ static int64_t klondike_scanwork(struct thr_info *thr) return newhashcount; } -static double convertKlnTemp(uint8_t temp) -{ - return (double)1/((double)1/(25+273.15) + log((double)temp*1000/(256-temp)/2200)/3987) - 273.15; -} static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) { @@ -504,7 +532,7 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) } rd_unlock(&(klninfo->stat_lock)); - tailsprintf(buf, " %3.0fC 1.2V | ", convertKlnTemp(temp)); + tailsprintf(buf, " %3.0fC 1.2V | ", cvtKlnToC(temp)); } static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) @@ -520,7 +548,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) rd_lock(&(klninfo->stat_lock)); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { - float fTemp = convertKlnTemp(klninfo->status[dev].temp); + float fTemp = cvtKlnToC(klninfo->status[dev].temp); sprintf(buf, "Temp %d", dev); root = api_add_temp(root, buf, &fTemp, true); From 63d8dbd3b65a2900a1f79b0756e26d18a6e350c4 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Mon, 8 Jul 2013 18:04:37 +0700 Subject: [PATCH 09/31] prevent nonces when not state W --- cgminer/driver-klondike.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index bd85fcad..c6933ea7 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -42,6 +42,7 @@ #define REPLY_BUFSIZE 16 // reply + 1 byte to mark used #define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss #define REPLY_WAIT_TIME 100 // poll interval for a cmd waiting it's reply +#define CMD_REPLY_RETRIES 8 // how many retries for cmds #define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware #define TACH_FACTOR 87890 // fan rpm divisor @@ -124,7 +125,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); char outbuf[64]; - int retries = 10; + int retries = CMD_REPLY_RETRIES; int chkreply = klninfo->nextreply; int sent, err; @@ -138,7 +139,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in if (err < 0 || sent != 2+datalen) { applog(LOG_ERR, "%s (%s) Cmd:%c Dev:%d, write failed (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, Cmd, device, sent, err); } - while(retries-- > 0) { + while(retries-- > 0 && klninfo->shutdown == false) { nmsleep(REPLY_WAIT_TIME); while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd || *(klninfo->replies + chkreply*REPLY_BUFSIZE + 2) != device) { if(++chkreply == MAX_REPLY_COUNT) @@ -244,7 +245,6 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic klninfo = calloc(1, sizeof(*klninfo)); if (unlikely(!klninfo)) quit(1, "Failed to calloc klninfo in klondke_detect_one"); - // TODO: fix ... everywhere ... klncgpu->device_data = (FILE *)klninfo; klninfo->replies = calloc(MAX_REPLY_COUNT, REPLY_BUFSIZE); @@ -283,6 +283,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic } usb_uninit(klncgpu); } + free(klninfo->replies); free(klncgpu); return false; } @@ -363,7 +364,7 @@ static void klondike_flush_work(struct cgpu_info *klncgpu) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int dev; - applog(LOG_DEBUG, "Klondike flushing work work"); + applog(LOG_DEBUG, "Klondike flushing work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); if(reply != NULL) { @@ -408,12 +409,13 @@ static void klondike_shutdown(struct thr_info *thr) { struct cgpu_info *klncgpu = thr->cgpu; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - - //SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); - - klondike_flush_work(klncgpu); + int dev; - klninfo->shutdown = true; + applog(LOG_DEBUG, "Klondike shutting down work"); + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + SendCmdGetReply(klncgpu, 'E', dev, 1, "0"); + } + klncgpu->shutdown = klninfo->shutdown = true; } static void klondike_thread_enable(struct thr_info *thr) @@ -423,7 +425,7 @@ static void klondike_thread_enable(struct thr_info *thr) if (klncgpu->usbinfo.nodev) return; - SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); + //SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); } @@ -507,7 +509,7 @@ static int64_t klondike_scanwork(struct thr_info *thr) klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; - // check stats for critical conditions + // todo: check stats for critical conditions } rd_unlock(&(klninfo->stat_lock)); From 3d6cd8e3f25eecc662b2f205b8d55dc487948ee2 Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Thu, 11 Jul 2013 18:50:57 +0700 Subject: [PATCH 10/31] updated firmware, IOC method --- cgminer/driver-klondike.c | 88 ++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 30 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index c6933ea7..d8020ec8 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -94,7 +94,9 @@ typedef struct device_info { uint32_t noncecount; uint32_t nextworkid; uint16_t lasthashcount; - uint64_t totalhashcount; + uint64_t totalhashcount; + uint32_t rangesize; + uint32_t *chipstats; } DEVINFO; struct klondike_info { @@ -154,6 +156,31 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in } return NULL; } + +static bool klondike_get_stats(struct cgpu_info *klncgpu) +{ + struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + int slaves, dev; + + if (klncgpu->usbinfo.nodev || klninfo->status == NULL) + return false; + + applog(LOG_DEBUG, "Klondike getting status"); + slaves = klninfo->status[0].slavecount; + + // loop thru devices and get status for each + wr_lock(&(klninfo->stat_lock)); + for(dev = 0; dev <= slaves; dev++) { + char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); + if(reply != NULL) + klninfo->status[dev] = *(WORKSTATUS *)(reply+2); + } + wr_unlock(&(klninfo->stat_lock)); + + // todo: detect slavecount change and realloc space + + return true; +} static bool klondike_init(struct cgpu_info *klncgpu) { @@ -203,36 +230,16 @@ static bool klondike_init(struct cgpu_info *klncgpu) (int)100*klninfo->cfg[dev].fantarget/256); } } + klondike_get_stats(klncgpu); + for(dev = 0; dev <= slaves; dev++) { + klninfo->devinfo[dev].rangesize = ((uint64_t)1<<32) / klninfo->status[dev].chipcount; + klninfo->devinfo[dev].chipstats = calloc(klninfo->status[dev].chipcount*2 , sizeof(uint32_t)); + } SendCmdGetReply(klncgpu, 'E', 0, 1, "1"); return true; } - -static bool klondike_get_stats(struct cgpu_info *klncgpu) -{ - struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - int slaves, dev; - - if (klncgpu->usbinfo.nodev || klninfo->status == NULL) - return false; - - applog(LOG_DEBUG, "Klondike getting status"); - slaves = klninfo->status[0].slavecount; - - // loop thru devices and get status for each - wr_lock(&(klninfo->stat_lock)); - for(dev = 0; dev <= slaves; dev++) { - char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); - if(reply != NULL) - klninfo->status[dev] = *(WORKSTATUS *)(reply+2); - } - wr_unlock(&(klninfo->stat_lock)); - - // todo: detect slavecount change and realloc space - - return true; -} static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devices *found) { @@ -314,12 +321,15 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) result->nonce = le32toh(result->nonce - 0xC0); applog(LOG_DEBUG, "Klondike SUBMIT NONCE (%02x:%08x)", result->workid, result->nonce); - submit_nonce(klncgpu->thr[0], work, result->nonce); + bool ok = submit_nonce(klncgpu->thr[0], work, result->nonce); + + applog(LOG_DEBUG, "Klondike chip stats %d, %08x, %d, %d", result->device, result->nonce, klninfo->devinfo[result->device].rangesize, klninfo->status[result->device].chipcount); + klninfo->devinfo[result->device].chipstats[(result->nonce / klninfo->devinfo[result->device].rangesize) + (ok ? 0 : klninfo->status[result->device].chipcount)]++; return; } } - applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - can't be processed - ignored", + applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - ignored", klncgpu->drv->name, klncgpu->device_id, result->device, result->workid, result->nonce); //inc_hw_errors(klncgpu->thr[0]); } @@ -458,7 +468,7 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * // remove old work HASH_ITER(hh, klncgpu->queued_work, work, tmp) { - if (work->queued && (work->subid == (dev*256 + data.workid-2*MAX_WORK_COUNT))) + if (work->queued && (work->subid == (dev*256 + ((klninfo->devinfo[dev].nextworkid-2*MAX_WORK_COUNT) & 0xFF)))) work_completed(klncgpu, work); } return true; @@ -562,9 +572,27 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) sprintf(buf, "Fan Percent %d", dev); root = api_add_int(root, buf, &iFan, true); - iFan = (unsigned int)TACH_FACTOR / klninfo->status[dev].fanspeed; + iFan = 0; + if(klninfo->status[dev].fanspeed > 0) + iFan = (unsigned int)TACH_FACTOR / klninfo->status[dev].fanspeed; sprintf(buf, "Fan RPM %d", dev); root = api_add_int(root, buf, &iFan, true); + + if(klninfo->devinfo[dev].chipstats != NULL) { + char data[80]; + int n; + sprintf(buf, "Nonces / Chip %d", dev); + for(n = 0; n < klninfo->status[dev].chipcount; n++) + sprintf(data+n*5, "%04d ", klninfo->devinfo[dev].chipstats[n]); + data[79] = 0; + root = api_add_string(root, buf, data, true); + + sprintf(buf, "Errors / Chip %d", dev); + for(n = 0; n < klninfo->status[dev].chipcount; n++) + sprintf(data+n*5, "%04d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); + data[79] = 0; + root = api_add_string(root, buf, data, true); + } } rd_unlock(&(klninfo->stat_lock)); From eeaaabbbe67144d2a68923df6e5f1549170b4d7d Mon Sep 17 00:00:00 2001 From: bkkcoins Date: Tue, 16 Jul 2013 03:01:52 +0700 Subject: [PATCH 11/31] beta final 0.3.0 release --- cgminer/driver-klondike.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index d8020ec8..351fcb3b 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -215,7 +215,7 @@ static bool klondike_init(struct cgpu_info *klncgpu) sscanf(opt_klondike_options, "%hu,%lf,%lf,%hhu", &cfgset.hashclock, &temp1, &temp2, &cfgset.fantarget); cfgset.temptarget = cvtCToKln(temp1); cfgset.tempcritical = cvtCToKln(temp2); - cfgset.fantarget = (int)256*cfgset.fantarget/100; + cfgset.fantarget = (int)255*cfgset.fantarget/100; size = sizeof(cfgset); } @@ -532,6 +532,7 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); uint8_t temp = 0xFF; + uint16_t fan = 0; int dev; if(klninfo->status == NULL) @@ -541,10 +542,12 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) for (dev = 0; dev <= klninfo->status->slavecount; dev++) { if (klninfo->status[dev].temp < temp) temp = klninfo->status[dev].temp; + fan += klninfo->cfg[dev].fantarget; } + fan /= klninfo->status->slavecount+1; rd_unlock(&(klninfo->stat_lock)); - tailsprintf(buf, " %3.0fC 1.2V | ", cvtKlnToC(temp)); + tailsprintf(buf, " %3.0fC %3d% | ", cvtKlnToC(temp), fan*100/255); } static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) @@ -568,7 +571,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) sprintf(buf, "Clock %d", dev); root = api_add_freq(root, buf, &dClk, true); - unsigned int iFan = (unsigned int)100 * klninfo->cfg[dev].fantarget / 256; + unsigned int iFan = (unsigned int)100 * klninfo->cfg[dev].fantarget / 255; sprintf(buf, "Fan Percent %d", dev); root = api_add_int(root, buf, &iFan, true); From e4638aa9860319bf015b645a1840930b9f9e9b75 Mon Sep 17 00:00:00 2001 From: Chris Savery Date: Fri, 16 Aug 2013 12:47:04 +0700 Subject: [PATCH 12/31] update firmware for 16 chips, add dist files --- cgminer/driver-klondike.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 351fcb3b..5ef2fb52 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -567,7 +567,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) sprintf(buf, "Temp %d", dev); root = api_add_temp(root, buf, &fTemp, true); - double dClk = (double)klninfo->cfg[dev].hashclock / 2; + double dClk = (double)klninfo->cfg[dev].hashclock; sprintf(buf, "Clock %d", dev); root = api_add_freq(root, buf, &dClk, true); @@ -582,18 +582,18 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) root = api_add_int(root, buf, &iFan, true); if(klninfo->devinfo[dev].chipstats != NULL) { - char data[80]; + char data[128]; int n; sprintf(buf, "Nonces / Chip %d", dev); for(n = 0; n < klninfo->status[dev].chipcount; n++) - sprintf(data+n*5, "%04d ", klninfo->devinfo[dev].chipstats[n]); - data[79] = 0; + sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n]); + data[127] = 0; root = api_add_string(root, buf, data, true); sprintf(buf, "Errors / Chip %d", dev); for(n = 0; n < klninfo->status[dev].chipcount; n++) - sprintf(data+n*5, "%04d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); - data[79] = 0; + sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); + data[127] = 0; root = api_add_string(root, buf, data, true); } } From 4d2fa5bf176c2b95cb74e64fd24831a034124a77 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 10 Sep 2013 12:36:50 +1000 Subject: [PATCH 13/31] Klondike update driver code to current git --- cgminer/driver-klondike.c | 95 +++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index 5ef2fb52..f9d9c994 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -38,13 +38,13 @@ #define MERKLE_OFFSET 64 #define MERKLE_BYTES 12 -#define REPLY_SIZE 15 // adequate for all types of replies -#define REPLY_BUFSIZE 16 // reply + 1 byte to mark used -#define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss +#define REPLY_SIZE 15 // adequate for all types of replies +#define REPLY_BUFSIZE 16 // reply + 1 byte to mark used +#define MAX_REPLY_COUNT 32 // more unhandled replies than this will result in data loss #define REPLY_WAIT_TIME 100 // poll interval for a cmd waiting it's reply -#define CMD_REPLY_RETRIES 8 // how many retries for cmds -#define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware -#define TACH_FACTOR 87890 // fan rpm divisor +#define CMD_REPLY_RETRIES 8 // how many retries for cmds +#define MAX_WORK_COUNT 4 // for now, must be binary multiple and match firmware +#define TACH_FACTOR 87890 // fan rpm divisor struct device_drv klondike_drv; @@ -70,16 +70,16 @@ typedef struct klondike_status { typedef struct _worktask { uint16_t pad1; uint8_t pad2; - uint8_t workid; - uint32_t midstate[8]; - uint32_t merkle[3]; + uint8_t workid; + uint32_t midstate[8]; + uint32_t merkle[3]; } WORKTASK; typedef struct _workresult { uint16_t pad; uint8_t device; - uint8_t workid; - uint32_t nonce; + uint8_t workid; + uint32_t nonce; } WORKRESULT; typedef struct kondike_cfg { @@ -142,14 +142,14 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in applog(LOG_ERR, "%s (%s) Cmd:%c Dev:%d, write failed (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, Cmd, device, sent, err); } while(retries-- > 0 && klninfo->shutdown == false) { - nmsleep(REPLY_WAIT_TIME); + cgsleep_ms(REPLY_WAIT_TIME); while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd || *(klninfo->replies + chkreply*REPLY_BUFSIZE + 2) != device) { - if(++chkreply == MAX_REPLY_COUNT) + if (++chkreply == MAX_REPLY_COUNT) chkreply = 0; - if(chkreply == klninfo->nextreply) + if (chkreply == klninfo->nextreply) break; } - if(chkreply == klninfo->nextreply) + if (chkreply == klninfo->nextreply) continue; *(klninfo->replies + chkreply*REPLY_BUFSIZE) = '!'; // mark to prevent re-use return klninfo->replies + chkreply*REPLY_BUFSIZE + 1; @@ -172,7 +172,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) wr_lock(&(klninfo->stat_lock)); for(dev = 0; dev <= slaves; dev++) { char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); - if(reply != NULL) + if (reply != NULL) klninfo->status[dev] = *(WORKSTATUS *)(reply+2); } wr_unlock(&(klninfo->stat_lock)); @@ -188,11 +188,11 @@ static bool klondike_init(struct cgpu_info *klncgpu) int slaves, dev; char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); - if(reply == NULL) + if (reply == NULL) return false; slaves = ((WORKSTATUS *)(reply+2))->slavecount; - if(klninfo->status == NULL) { + if (klninfo->status == NULL) { applog(LOG_DEBUG, "Klondike initializing data"); // alloc space for status, devinfo and cfg for master and slaves @@ -211,17 +211,17 @@ static bool klondike_init(struct cgpu_info *klncgpu) double temp1, temp2; int size = 2; - if(opt_klondike_options != NULL) { // boundaries are checked by device, with valid values returned - sscanf(opt_klondike_options, "%hu,%lf,%lf,%hhu", &cfgset.hashclock, &temp1, &temp2, &cfgset.fantarget); + if (opt_klondike_options != NULL) { // boundaries are checked by device, with valid values returned + sscanf(opt_klondike_options, "%hu:%lf:%lf:%hhu", &cfgset.hashclock, &temp1, &temp2, &cfgset.fantarget); cfgset.temptarget = cvtCToKln(temp1); cfgset.tempcritical = cvtCToKln(temp2); cfgset.fantarget = (int)255*cfgset.fantarget/100; size = sizeof(cfgset); } - for(dev = 0; dev <= slaves; dev++) { + for (dev = 0; dev <= slaves; dev++) { char *reply = SendCmdGetReply(klncgpu, 'C', dev, size, &cfgset); - if(reply != NULL) { + if (reply != NULL) { klninfo->cfg[dev] = *(WORKCFG *)(reply+2); applog(LOG_NOTICE, "Klondike config (%d: Clk: %d, T:%.0lf, C:%.0lf, F:%d)", dev, klninfo->cfg[dev].hashclock, @@ -231,7 +231,7 @@ static bool klondike_init(struct cgpu_info *klncgpu) } } klondike_get_stats(klncgpu); - for(dev = 0; dev <= slaves; dev++) { + for (dev = 0; dev <= slaves; dev++) { klninfo->devinfo[dev].rangesize = ((uint64_t)1<<32) / klninfo->status[dev].chipcount; klninfo->devinfo[dev].chipstats = calloc(klninfo->status[dev].chipcount*2 , sizeof(uint32_t)); } @@ -270,19 +270,19 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic if (err < 0 || sent != 2) { applog(LOG_ERR, "%s (%s) detect write failed (%d:%d)", klncgpu->drv->dname, devpath, sent, err); } - nmsleep(REPLY_WAIT_TIME*10); + cgsleep_ms(REPLY_WAIT_TIME*10); err = usb_read(klncgpu, reply, REPLY_SIZE, &recd, C_GETRESULTS); if (err < 0) { applog(LOG_ERR, "%s (%s) detect read failed (%d:%d)", klncgpu->drv->dname, devpath, recd, err); } else if (recd < 1) { applog(LOG_ERR, "%s (%s) detect empty reply (%d)", klncgpu->drv->dname, devpath, recd); - } else if(reply[0] == 'I' && reply[1] == 0) { + } else if (reply[0] == 'I' && reply[1] == 0) { applog(LOG_DEBUG, "%s (%s) detect successful", klncgpu->drv->dname, devpath); KlondikeID = *(IDENTITY *)(&reply[2]); klncgpu->device_path = strdup(devpath); update_usb_stats(klncgpu); - if(!add_cgpu(klncgpu)) + if (!add_cgpu(klncgpu)) break; applog(LOG_DEBUG, "Klondike cgpu added"); return true; @@ -300,7 +300,7 @@ static void klondike_detect(void) usb_detect(&klondike_drv, klondike_detect_one); } -static void klondike_identify(struct cgpu_info *klncgpu) +static void klondike_identify(__maybe_unused struct cgpu_info *klncgpu) { //SendCmdGetReply(klncgpu, 'I', 0, 0, NULL); } @@ -352,17 +352,17 @@ static void *klondike_get_replies(void *userdata) replybuf[0] = 0; err = usb_read(klncgpu, replybuf+1, REPLY_SIZE, &recd, C_GETRESULTS); - if (recd == REPLY_SIZE) { - if(opt_log_level <= LOG_DEBUG) { - char *hexdata = bin2hex(replybuf+1, recd); + if (!err && recd == REPLY_SIZE) { + if (opt_log_level <= LOG_DEBUG) { + char *hexdata = bin2hex((unsigned char *)(replybuf+1), recd); applog(LOG_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); free(hexdata); } - if(++klninfo->nextreply == MAX_REPLY_COUNT) + if (++klninfo->nextreply == MAX_REPLY_COUNT) klninfo->nextreply = 0; replybuf[0] = replybuf[1]; - if(replybuf[0] == '=') + if (replybuf[0] == '=') klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); } } @@ -377,7 +377,7 @@ static void klondike_flush_work(struct cgpu_info *klncgpu) applog(LOG_DEBUG, "Klondike flushing work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); - if(reply != NULL) { + if (reply != NULL) { wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); @@ -389,7 +389,6 @@ static bool klondike_thread_prepare(struct thr_info *thr) { struct cgpu_info *klncgpu = thr->cgpu; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - struct timeval now; if (thr_info_create(&(klninfo->replies_thr), NULL, klondike_get_replies, (void *)klncgpu)) { applog(LOG_ERR, "%s%i: thread create failed", klncgpu->drv->name, klncgpu->device_id); @@ -398,7 +397,7 @@ static bool klondike_thread_prepare(struct thr_info *thr) pthread_detach(klninfo->replies_thr.pth); // let the listening get started - nmsleep(100); + cgsleep_ms(100); return klondike_init(klncgpu); } @@ -453,7 +452,7 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * data.workid = (uint8_t)(klninfo->devinfo[dev].nextworkid++ & 0xFF); work->subid = dev*256 + data.workid; - if(opt_log_level <= LOG_DEBUG) { + if (opt_log_level <= LOG_DEBUG) { char *hexdata = bin2hex(&data.workid, sizeof(data)-3); applog(LOG_DEBUG, "WORKDATA: %s", hexdata); free(hexdata); @@ -461,14 +460,14 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * applog(LOG_DEBUG, "Klondike sending work (%d:%02x)", dev, data.workid); char *reply = SendCmdGetReply(klncgpu, 'W', dev, sizeof(data)-3, &data.workid); - if(reply != NULL) { + if (reply != NULL) { wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); // remove old work HASH_ITER(hh, klncgpu->queued_work, work, tmp) { - if (work->queued && (work->subid == (dev*256 + ((klninfo->devinfo[dev].nextworkid-2*MAX_WORK_COUNT) & 0xFF)))) + if (work->queued && (work->subid == (int)(dev*256 + ((klninfo->devinfo[dev].nextworkid-2*MAX_WORK_COUNT) & 0xFF)))) work_completed(klncgpu, work); } return true; @@ -508,12 +507,12 @@ static int64_t klondike_scanwork(struct thr_info *thr) if (klncgpu->usbinfo.nodev) return -1; - restart_wait(200); + restart_wait(thr, 200); if (klninfo->status != NULL) { rd_lock(&(klninfo->stat_lock)); for(dev = 0; dev <= klninfo->status->slavecount; dev++) { uint64_t newhashdev = 0; - if(klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) // todo: chg this to check workid for wrapped instead + if (klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) // todo: chg this to check workid for wrapped instead newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; @@ -528,14 +527,14 @@ static int64_t klondike_scanwork(struct thr_info *thr) } -static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) +static void get_klondike_statline_before(char *buf, size_t siz, struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); uint8_t temp = 0xFF; uint16_t fan = 0; int dev; - if(klninfo->status == NULL) + if (klninfo->status == NULL) return; rd_lock(&(klninfo->stat_lock)); @@ -547,7 +546,7 @@ static void get_klondike_statline_before(char *buf, struct cgpu_info *klncgpu) fan /= klninfo->status->slavecount+1; rd_unlock(&(klninfo->stat_lock)); - tailsprintf(buf, " %3.0fC %3d% | ", cvtKlnToC(temp), fan*100/255); + tailsprintf(buf, siz, " %3.0fC %3d%% | ", cvtKlnToC(temp), fan*100/255); } static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) @@ -557,7 +556,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) char buf[32]; int dev; - if(klninfo->status == NULL) + if (klninfo->status == NULL) return NULL; rd_lock(&(klninfo->stat_lock)); @@ -573,15 +572,15 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) unsigned int iFan = (unsigned int)100 * klninfo->cfg[dev].fantarget / 255; sprintf(buf, "Fan Percent %d", dev); - root = api_add_int(root, buf, &iFan, true); + root = api_add_int(root, buf, (int *)(&iFan), true); iFan = 0; - if(klninfo->status[dev].fanspeed > 0) + if (klninfo->status[dev].fanspeed > 0) iFan = (unsigned int)TACH_FACTOR / klninfo->status[dev].fanspeed; sprintf(buf, "Fan RPM %d", dev); - root = api_add_int(root, buf, &iFan, true); + root = api_add_int(root, buf, (int *)(&iFan), true); - if(klninfo->devinfo[dev].chipstats != NULL) { + if (klninfo->devinfo[dev].chipstats != NULL) { char data[128]; int n; sprintf(buf, "Nonces / Chip %d", dev); From 9621f013ee7d2177b3cea2a66b9402f810845e3f Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 10 Sep 2013 13:45:43 +1000 Subject: [PATCH 14/31] Klondike consistent code spacing --- cgminer/driver-klondike.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cgminer/driver-klondike.c b/cgminer/driver-klondike.c index f9d9c994..27e0196b 100644 --- a/cgminer/driver-klondike.c +++ b/cgminer/driver-klondike.c @@ -141,9 +141,9 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in if (err < 0 || sent != 2+datalen) { applog(LOG_ERR, "%s (%s) Cmd:%c Dev:%d, write failed (%d:%d)", klncgpu->drv->dname, klncgpu->device_path, Cmd, device, sent, err); } - while(retries-- > 0 && klninfo->shutdown == false) { + while (retries-- > 0 && klninfo->shutdown == false) { cgsleep_ms(REPLY_WAIT_TIME); - while(*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd || *(klninfo->replies + chkreply*REPLY_BUFSIZE + 2) != device) { + while (*(klninfo->replies + chkreply*REPLY_BUFSIZE) != Cmd || *(klninfo->replies + chkreply*REPLY_BUFSIZE + 2) != device) { if (++chkreply == MAX_REPLY_COUNT) chkreply = 0; if (chkreply == klninfo->nextreply) @@ -170,7 +170,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) // loop thru devices and get status for each wr_lock(&(klninfo->stat_lock)); - for(dev = 0; dev <= slaves; dev++) { + for (dev = 0; dev <= slaves; dev++) { char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); if (reply != NULL) klninfo->status[dev] = *(WORKSTATUS *)(reply+2); @@ -261,7 +261,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic if (usb_init(klncgpu, dev, found)) { int attempts = 0; - while(attempts++ < 3) { + while (attempts++ < 3) { char devpath[20], reply[REPLY_SIZE]; int sent, recd, err; @@ -481,8 +481,8 @@ static bool klondike_queue_full(struct cgpu_info *klncgpu) struct work *work = NULL; int dev, queued; - for(queued = 0; queued < MAX_WORK_COUNT-1; queued++) - for(dev = 0; dev <= klninfo->status->slavecount; dev++) + for (queued = 0; queued < MAX_WORK_COUNT-1; queued++) + for (dev = 0; dev <= klninfo->status->slavecount; dev++) if (klninfo->status[dev].workqc <= queued) { if (!work) work = get_queued(klncgpu); @@ -510,7 +510,7 @@ static int64_t klondike_scanwork(struct thr_info *thr) restart_wait(thr, 200); if (klninfo->status != NULL) { rd_lock(&(klninfo->stat_lock)); - for(dev = 0; dev <= klninfo->status->slavecount; dev++) { + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { uint64_t newhashdev = 0; if (klninfo->devinfo[dev].lasthashcount > klninfo->status[dev].hashcount) // todo: chg this to check workid for wrapped instead newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped @@ -584,13 +584,13 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) char data[128]; int n; sprintf(buf, "Nonces / Chip %d", dev); - for(n = 0; n < klninfo->status[dev].chipcount; n++) + for (n = 0; n < klninfo->status[dev].chipcount; n++) sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n]); data[127] = 0; root = api_add_string(root, buf, data, true); sprintf(buf, "Errors / Chip %d", dev); - for(n = 0; n < klninfo->status[dev].chipcount; n++) + for (n = 0; n < klninfo->status[dev].chipcount; n++) sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); data[127] = 0; root = api_add_string(root, buf, data, true); From 86045d81a4c5538debaa3f7b93d57a74a550f56a Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 10 Sep 2013 13:49:44 +1000 Subject: [PATCH 15/31] Klondike to main directory --- cgminer/driver-klondike.c => driver-klondike.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cgminer/driver-klondike.c => driver-klondike.c (100%) diff --git a/cgminer/driver-klondike.c b/driver-klondike.c similarity index 100% rename from cgminer/driver-klondike.c rename to driver-klondike.c From 45c8b58da254040f3d3d3f1bf60427415391166b Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 22:27:06 +1000 Subject: [PATCH 16/31] Add Klondike to 01-cgminer.rules --- 01-cgminer.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/01-cgminer.rules b/01-cgminer.rules index 24211b49..dbd0bef1 100644 --- a/01-cgminer.rules +++ b/01-cgminer.rules @@ -21,3 +21,6 @@ ATTRS{idVendor}=="221a", ATTRS{idProduct}=="0100", SUBSYSTEMS=="usb", ACTION=="a # BF1 ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="204b", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" + +#Klondike +ATTRS{idVendor}=="04d8", ATTRS{idProduct}=="f60a", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" From 778c6da639b83424c272b20ece56e86a0dca617f Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 22:29:26 +1000 Subject: [PATCH 17/31] Add 2nd CMR to 01-cgminer.rules --- 01-cgminer.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/01-cgminer.rules b/01-cgminer.rules index dbd0bef1..89443ad0 100644 --- a/01-cgminer.rules +++ b/01-cgminer.rules @@ -16,6 +16,9 @@ ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SUBSYSTEMS=="usb", ACTION=="a # Cairnsmore1 ATTRS{idVendor}=="067b", ATTRS{idProduct}=="0230", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" +# Cairnsmore1-2 +ATTRS{idVendor}=="0403", ATTRS{idProduct}=="8350", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" + # Ztex ATTRS{idVendor}=="221a", ATTRS{idProduct}=="0100", SUBSYSTEMS=="usb", ACTION=="add", MODE="0666", GROUP="plugdev" From f61140e004d51cbf7b99c10c169ff9408cb05c0c Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 22:32:52 +1000 Subject: [PATCH 18/31] Add Klondike to ASIC-README --- ASIC-README | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ASIC-README b/ASIC-README index 4da05ab0..55b76d83 100644 --- a/ASIC-README +++ b/ASIC-README @@ -1,10 +1,11 @@ SUPPORTED DEVICES -Currently supported devices include the Avalon (including BitBurner), the -Butterfly Labs SC range of devices, the ASICMINER block erupters and the BPMC -BF1 (bitfury) USB devices. No COM ports on windows or TTY devices will be used -by cgminer as it communicates directly with them via USB so it is normal for -them to not exist or be disconnected when cgminer is running. +Currently supported devices include the Avalon (including BitBurner and +Klondike), the Butterfly Labs SC range of devices, the ASICMINER block +erupters and the BPMC BF1 (bitfury) USB devices. No COM ports on windows or +TTY devices will be used by cgminer as it communicates directly with them +via USB so it is normal for them to not exist or be disconnected when +cgminer is running. The BFL devices should come up as one of the following: @@ -20,6 +21,10 @@ Avalon will come up as AVA. Avalon devices need the --enable-avalon option when compiling cgminer. +Klondike will come up as KLN. + +Klondike devices need the --enable-klondike option when compiling cgminer. + ASICMINER block erupters will come up as AMU. ASICMINER devices need the --enable-icarus option when compiling cgminer. @@ -98,6 +103,7 @@ ASIC SPECIFIC COMMANDS --avalon-temp Set avalon target temperature (default: 50) --bflsc-overheat Set overheat temperature where BFLSC devices throttle, 0 to disable (default: 90) --bitburner-voltage Set BitBurner core voltage, in millivolts +--klondike-options Set klondike options clock:temp1:temp2:fan AVALON DEVICES From a1d84775ab92a2c239eb251c9ebb05252ef31270 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 22:37:22 +1000 Subject: [PATCH 19/31] Add Klondike to README --- README | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README b/README index 3d98de50..5c739912 100644 --- a/README +++ b/README @@ -114,6 +114,7 @@ CGMiner specific configuration options: --enable-modminer Compile support for ModMiner FPGAs(default disabled) --enable-ztex Compile support for Ztex Board(default disabled) --enable-avalon Compile support for Avalon (default disabled) + --enable-klondike Compile support for Klondike (default disabled) --enable-scrypt Compile support for scrypt litecoin mining (default disabled) --without-curses Compile support for curses TUI (default enabled) @@ -269,8 +270,8 @@ See SCRYPT-README for more information regarding litecoin mining. Cgminer should automatically find all of your Avalon ASIC, BFL ASIC, BitForce -FPGAs, Icarus bitstream FPGAs, ASICMINER usb block erupters, ModMiner FPGAs, -or Ztex FPGAs +FPGAs, Icarus bitstream FPGAs, Klondike ASIC, ASICMINER usb block erupters, +ModMiner FPGAs or Ztex FPGAs --- @@ -314,11 +315,11 @@ just reboot. Advanced USB options: The --usb option can restrict how many Avalon, BFL ASIC, BitForce FPGAs, -ModMiner FPGAs or Icarus bitstream FPGAs it finds: +Klondike ASIC, ModMiner FPGAs or Icarus bitstream FPGAs it finds: --usb 1:2,1:3,1:4,1:* or - --usb BAS:1,BFL:1,MMQ:0,ICA:0 + --usb BAS:1,BFL:1,MMQ:0,ICA:0,KLN:0 or --usb :10 @@ -344,9 +345,10 @@ of details about each recognised USB device If you wish to see all USB devices, include the --usb-list-all option The second version - --usb BAS:1,BFL:1,MMQ:0,ICA:0 + --usb BAS:1,BFL:1,MMQ:0,ICA:0,KLN:0 allows you to specify how many devices to choose based on each device -driver cgminer has - there are currently 4 USB drivers: BAS, BFL, MMQ & ICA +driver cgminer has - there are currently 5 USB drivers: BAS, BFL, MMQ. +ICA & KLN N.B. you can only specify which device driver to limit, not the type of each device, e.g. with BAS:n you can limit how many BFL ASIC devices will be checked, but you cannot limit the number of each type of BFL ASIC From dc85abd9cd0de732b0373baffad728b509c5680a Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 23:19:18 +1000 Subject: [PATCH 20/31] Klondike update code to current git --- Makefile.am | 4 ++++ cgminer.c | 24 ++++++++++++++++++++++++ configure.ac | 23 ++++++++++++++++++++--- driver-klondike.c | 7 +++---- miner.h | 6 +++++- usbutils.c | 26 ++++++++++++++++++++++++++ usbutils.h | 1 + 7 files changed, 83 insertions(+), 8 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2389d670..ae6b8293 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,6 +88,10 @@ if HAS_AVALON cgminer_SOURCES += driver-avalon.c driver-avalon.h endif +if HAS_KLONDIKE +cgminer_SOURCES += driver-klondike.c +endif + if HAS_MODMINER cgminer_SOURCES += driver-modminer.c bitstreamsdir = $(bindir)/bitstreams diff --git a/cgminer.c b/cgminer.c index 337722a7..7f136cd8 100644 --- a/cgminer.c +++ b/cgminer.c @@ -166,6 +166,9 @@ bool opt_worktime; #ifdef USE_AVALON char *opt_avalon_options = NULL; #endif +#ifdef USE_KLONDIKE +char *opt_klondike_options = NULL; +#endif #ifdef USE_USBUTILS char *opt_usb_select = NULL; int opt_usbdump = -1; @@ -1026,6 +1029,15 @@ static char *set_avalon_options(const char *arg) } #endif +#ifdef USE_KLONDIKE +static char *set_klondike_options(const char *arg) +{ + opt_set_charp(arg, &opt_klondike_options); + + return NULL; +} +#endif + #ifdef USE_USBUTILS static char *set_usb_select(const char *arg) { @@ -1231,6 +1243,11 @@ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--bitburner-voltage", opt_set_intval, NULL, &opt_bitburner_core_voltage, "Set BitBurner core voltage, in millivolts"), +#endif +#ifdef USE_KLONDIKE + OPT_WITH_ARG("--klondike-options", + set_klondike_options, NULL, NULL, + "Set klondike options clock:temp1:temp2:fan"), #endif OPT_WITHOUT_ARG("--load-balance", set_loadbalance, &pool_strategy, @@ -1572,6 +1589,9 @@ static char *opt_verusage_and_exit(const char *extra) #ifdef USE_ICARUS "icarus " #endif +#ifdef USE_KLONDIKE + "klondike " +#endif #ifdef USE_MODMINER "modminer " #endif @@ -4430,6 +4450,10 @@ void write_config(FILE *fcfg) fprintf(fcfg, ",\n\"icarus-options\" : \"%s\"", json_escape(opt_icarus_options)); if (opt_icarus_timing) fprintf(fcfg, ",\n\"icarus-timing\" : \"%s\"", json_escape(opt_icarus_timing)); +#ifdef USE_KLONDIKE + if (opt_klondike_options) + fprintf(fcfg, ",\n\"klondike-options\" : \"%s\"", json_escape(opt_icarus_options)); +#endif #ifdef USE_USBUTILS if (opt_usb_select) fprintf(fcfg, ",\n\"usb\" : \"%s\"", json_escape(opt_usb_select)); diff --git a/configure.ac b/configure.ac index 95795bc5..9781f9df 100644 --- a/configure.ac +++ b/configure.ac @@ -275,6 +275,17 @@ if test "x$avalon" = xyes; then fi AM_CONDITIONAL([HAS_AVALON], [test x$avalon = xyes]) +klondike="no" + +AC_ARG_ENABLE([klondike], + [AC_HELP_STRING([--enable-klondike],[Compile support for Klondike (default disabled)])], + [klondike=$enableval] + ) +if test "x$klondike" = xyes; then + AC_DEFINE([USE_KLONDIKE], [1], [Defined to 1 if Klondike support is wanted]) +fi +AM_CONDITIONAL([HAS_KLONDIKE], [test x$klondike = xyes]) + modminer="no" AC_ARG_ENABLE([modminer], @@ -321,7 +332,7 @@ else ]) fi -if test x$avalon$bitforce$bitfury$modminer$bflsc$icarus != xnononononono; then +if test x$avalon$bitforce$bitfury$modminer$bflsc$icarus$klondike != xnonononononono; then want_usbutils=true else want_usbutils=false @@ -493,14 +504,14 @@ if test "x$opencl" != xno; then else echo " OpenCL...............: NOT FOUND. GPU mining support DISABLED" - if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc" = xnonononononono; then + if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc$klondike" = xnononononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" fi else echo " OpenCL...............: Detection overrided. GPU mining support DISABLED" - if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc" = xnonononononono; then + if test "x$avalon$bitforce$bitfury$icarus$ztex$modminer$bflsc$klondike" = xnononononononono; then AC_MSG_ERROR([No mining configured in]) fi echo " scrypt...............: Disabled (needs OpenCL)" @@ -547,6 +558,12 @@ else echo " Icarus.FPGAs.........: Disabled" fi +if test "x$klondike" = xyes; then + echo " Klondike.ASICs.......: Enabled" +else + echo " Klondike.ASICs.......: Disabled" +fi + if test "x$modminer" = xyes; then echo " ModMiner.FPGAs.......: Enabled" else diff --git a/driver-klondike.c b/driver-klondike.c index 27e0196b..8480d949 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -29,7 +29,6 @@ #include "miner.h" #include "usbutils.h" -#define KLN "KLN" #define K1 "K1" #define K16 "K16" #define K64 "K64" @@ -295,7 +294,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic return false; } -static void klondike_detect(void) +static void klondike_detect(bool __maybe_unused hotplug) { usb_detect(&klondike_drv, klondike_detect_one); } @@ -602,9 +601,9 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) } struct device_drv klondike_drv = { - .drv_id = DRIVER_KLONDIKE, + .drv_id = DRIVER_klondike, .dname = "Klondike", - .name = KLN, + .name = "KLN", .drv_detect = klondike_detect, .get_api_stats = klondike_api_stats, .get_statline_before = get_klondike_statline_before, diff --git a/miner.h b/miner.h index 7bafed01..6dab8366 100644 --- a/miner.h +++ b/miner.h @@ -243,7 +243,8 @@ static inline int fsync (int fd) #define ASIC_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ DRIVER_ADD_COMMAND(bflsc) \ DRIVER_ADD_COMMAND(bitfury) \ - DRIVER_ADD_COMMAND(avalon) + DRIVER_ADD_COMMAND(avalon) \ + DRIVER_ADD_COMMAND(klondike) #define DRIVER_PARSE_COMMANDS(DRIVER_ADD_COMMAND) \ DRIVER_ADD_COMMAND(opencl) \ @@ -943,6 +944,9 @@ extern bool opt_worktime; #ifdef USE_AVALON extern char *opt_avalon_options; #endif +#ifdef USE_KLONDIKE +extern char *opt_klondike_options; +#endif #ifdef USE_USBUTILS extern char *opt_usb_select; extern int opt_usbdump; diff --git a/usbutils.c b/usbutils.c index 40bef6a0..e2fa88b9 100644 --- a/usbutils.c +++ b/usbutils.c @@ -50,6 +50,7 @@ #define BITFURY_TIMEOUT_MS 999 #define MODMINER_TIMEOUT_MS 999 #define AVALON_TIMEOUT_MS 999 +#define KLONDIKE_TIMEOUT_MS 999 #define ICARUS_TIMEOUT_MS 999 #else #define BFLSC_TIMEOUT_MS 300 @@ -57,6 +58,7 @@ #define BITFURY_TIMEOUT_MS 100 #define MODMINER_TIMEOUT_MS 100 #define AVALON_TIMEOUT_MS 200 +#define KLONDIKE_TIMEOUT_MS 200 #define ICARUS_TIMEOUT_MS 200 #endif @@ -139,6 +141,17 @@ static struct usb_intinfo ava_ints[] = { }; #endif +#ifdef USE_KLONDIKE +static struct usb_epinfo kln_epinfos[] = { + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(1), 0, 0, 0 }, + { LIBUSB_TRANSFER_TYPE_BULK, 64, EPO(1), 0, 0, 0 } +}; + +static struct usb_intinfo kln_ints[] = { + USB_EPS(0, kln_epinfos) +}; +#endif + #ifdef USE_ICARUS static struct usb_epinfo ica_epinfos[] = { { LIBUSB_TRANSFER_TYPE_BULK, 64, EPI(3), 0, 0, 0 }, @@ -292,6 +305,18 @@ static struct usb_find_devices find_dev[] = { .latency = 10, INTINFO(ava_ints) }, #endif +#ifdef USE_KLONDIKE + { + .drv = DRIVER_klondike, + .name = "KLN", + .ident = IDENT_KLN, + .idVendor = 0x04D8, + .idProduct = 0xF60A, + .config = 1, + .timeout = KLONDIKE_TIMEOUT_MS, + .latency = 10, + INTINFO(kln_ints) }, +#endif #ifdef USE_ICARUS { .drv = DRIVER_icarus, @@ -3103,6 +3128,7 @@ void usb_cleanup() case DRIVER_modminer: case DRIVER_icarus: case DRIVER_avalon: + case DRIVER_klondike: mutex_lock(cgpu->usbinfo.devlock); release_cgpu(cgpu); mutex_unlock(cgpu->usbinfo.devlock); diff --git a/usbutils.h b/usbutils.h index 457381d0..7b499eeb 100644 --- a/usbutils.h +++ b/usbutils.h @@ -144,6 +144,7 @@ enum sub_ident { IDENT_MMQ, IDENT_AVA, IDENT_BTB, + IDENT_KLN, IDENT_ICA, IDENT_AMU, IDENT_BLT, From 521ee0a97f269dfb2840cb39ef3adb6bf9433360 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 3 Oct 2013 23:21:03 +1000 Subject: [PATCH 21/31] api.c missing Klondike from ASIC list --- api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.c b/api.c index ab84faa0..ea35710d 100644 --- a/api.c +++ b/api.c @@ -29,7 +29,7 @@ #include "miner.h" #include "util.h" -#if defined(USE_BFLSC) || defined(USE_AVALON) || defined(USE_BITFURY) +#if defined(USE_BFLSC) || defined(USE_AVALON) || defined(USE_BITFURY) || defined(USE_KLONDIKE) #define HAVE_AN_ASIC 1 #endif From 9b6ae5bc42e19a4e0c12c4ee78441d50b3952f49 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 12 Sep 2013 21:49:23 +1000 Subject: [PATCH 22/31] klondike fix bracket tabs indenting --- driver-klondike.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/driver-klondike.c b/driver-klondike.c index 8480d949..0ebdd7aa 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -147,7 +147,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in chkreply = 0; if (chkreply == klninfo->nextreply) break; - } + } if (chkreply == klninfo->nextreply) continue; *(klninfo->replies + chkreply*REPLY_BUFSIZE) = '!'; // mark to prevent re-use @@ -173,7 +173,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); if (reply != NULL) klninfo->status[dev] = *(WORKSTATUS *)(reply+2); - } + } wr_unlock(&(klninfo->stat_lock)); // todo: detect slavecount change and realloc space @@ -204,7 +204,7 @@ static bool klondike_init(struct cgpu_info *klncgpu) klninfo->cfg = calloc(slaves+1, sizeof(WORKCFG)); if (unlikely(!klninfo->cfg)) quit(1, "Failed to calloc cfg array in klondke_get_stats"); - } + } WORKCFG cfgset = { 0,0,0,0,0 }; // zero init triggers read back only double temp1, temp2; @@ -227,8 +227,8 @@ static bool klondike_init(struct cgpu_info *klncgpu) cvtKlnToC(klninfo->cfg[dev].temptarget), cvtKlnToC(klninfo->cfg[dev].tempcritical), (int)100*klninfo->cfg[dev].fantarget/256); - } } + } klondike_get_stats(klncgpu); for (dev = 0; dev <= slaves; dev++) { klninfo->devinfo[dev].rangesize = ((uint64_t)1<<32) / klninfo->status[dev].chipcount; @@ -285,7 +285,7 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic break; applog(LOG_DEBUG, "Klondike cgpu added"); return true; - } + } } usb_uninit(klncgpu); } @@ -325,8 +325,8 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) applog(LOG_DEBUG, "Klondike chip stats %d, %08x, %d, %d", result->device, result->nonce, klninfo->devinfo[result->device].rangesize, klninfo->status[result->device].chipcount); klninfo->devinfo[result->device].chipstats[(result->nonce / klninfo->devinfo[result->device].rangesize) + (ok ? 0 : klninfo->status[result->device].chipcount)]++; return; - } } + } applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - ignored", klncgpu->drv->name, klncgpu->device_id, result->device, result->workid, result->nonce); @@ -452,10 +452,10 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * work->subid = dev*256 + data.workid; if (opt_log_level <= LOG_DEBUG) { - char *hexdata = bin2hex(&data.workid, sizeof(data)-3); - applog(LOG_DEBUG, "WORKDATA: %s", hexdata); - free(hexdata); - } + char *hexdata = bin2hex(&data.workid, sizeof(data)-3); + applog(LOG_DEBUG, "WORKDATA: %s", hexdata); + free(hexdata); + } applog(LOG_DEBUG, "Klondike sending work (%d:%02x)", dev, data.workid); char *reply = SendCmdGetReply(klncgpu, 'W', dev, sizeof(data)-3, &data.workid); @@ -518,7 +518,6 @@ static int64_t klondike_scanwork(struct thr_info *thr) newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; // todo: check stats for critical conditions - } rd_unlock(&(klninfo->stat_lock)); } @@ -541,7 +540,7 @@ static void get_klondike_statline_before(char *buf, size_t siz, struct cgpu_info if (klninfo->status[dev].temp < temp) temp = klninfo->status[dev].temp; fan += klninfo->cfg[dev].fantarget; - } + } fan /= klninfo->status->slavecount+1; rd_unlock(&(klninfo->stat_lock)); From 7cbe0dbf398c50ef6648babc1c307f526fcbd037 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 19 Sep 2013 23:23:36 +1000 Subject: [PATCH 23/31] klondike use a memcpy --- driver-klondike.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index 0ebdd7aa..78f9beca 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -172,7 +172,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) for (dev = 0; dev <= slaves; dev++) { char *reply = SendCmdGetReply(klncgpu, 'S', dev, 0, NULL); if (reply != NULL) - klninfo->status[dev] = *(WORKSTATUS *)(reply+2); + memcpy((void *)(&(klninfo->status[dev])), reply+2, sizeof(klninfo->status[dev])); } wr_unlock(&(klninfo->stat_lock)); From d7ce4493d63be285ed20e8ae029b905f23b464eb Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 22 Sep 2013 22:56:24 +1000 Subject: [PATCH 24/31] klondike - report mh/s based on nonces found + put old estimate into API stats --- driver-klondike.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index 78f9beca..7ee8e1a8 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -107,6 +107,8 @@ struct klondike_info { WORKCFG *cfg; char *replies; int nextreply; + int noncecount; + uint64_t hashcount; }; IDENTITY KlondikeID; @@ -316,6 +318,7 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) wr_lock(&(klninfo->stat_lock)); klninfo->devinfo[result->device].noncecount++; + klninfo->noncecount++; wr_unlock(&(klninfo->stat_lock)); result->nonce = le32toh(result->nonce - 0xC0); @@ -515,7 +518,8 @@ static int64_t klondike_scanwork(struct thr_info *thr) newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; - newhashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; + klninfo->hashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; + newhashcount += 0xffffffffull * (uint64_t)klninfo->noncecount; // todo: check stats for critical conditions } @@ -594,6 +598,9 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) root = api_add_string(root, buf, data, true); } } + + root = api_add_uint64(root, "Hash Count", &(klninfo->hashcount), true); + rd_unlock(&(klninfo->stat_lock)); return root; From 9b1ac1796f6d4d26ee732df325b3edbad7220999 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 22 Sep 2013 23:41:06 +1000 Subject: [PATCH 25/31] klondike add new nonecount only once --- driver-klondike.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index 7ee8e1a8..b11c21d6 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -519,10 +519,11 @@ static int64_t klondike_scanwork(struct thr_info *thr) newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; klninfo->hashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; - newhashcount += 0xffffffffull * (uint64_t)klninfo->noncecount; // todo: check stats for critical conditions } + newhashcount += 0xffffffffull * (uint64_t)klninfo->noncecount; + klninfo->noncecount = 0; rd_unlock(&(klninfo->stat_lock)); } return newhashcount; From 0fd939e714f1df31223897de6bc6528e0a393623 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 23 Sep 2013 09:01:00 +1000 Subject: [PATCH 26/31] klondike - fix chipstats api stats buffer overrun with 16 chips --- driver-klondike.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/driver-klondike.c b/driver-klondike.c index b11c21d6..1be043a5 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -584,18 +584,24 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) root = api_add_int(root, buf, (int *)(&iFan), true); if (klninfo->devinfo[dev].chipstats != NULL) { - char data[128]; + char data[2048]; + char one[32]; int n; + sprintf(buf, "Nonces / Chip %d", dev); - for (n = 0; n < klninfo->status[dev].chipcount; n++) - sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n]); - data[127] = 0; + data[0] = '\0'; + for (n = 0; n < klninfo->status[dev].chipcount; n++) { + snprintf(one, sizeof(one), "%07d ", klninfo->devinfo[dev].chipstats[n]); + strcat(data, one); + } root = api_add_string(root, buf, data, true); sprintf(buf, "Errors / Chip %d", dev); - for (n = 0; n < klninfo->status[dev].chipcount; n++) - sprintf(data+n*8, "%07d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); - data[127] = 0; + data[0] = '\0'; + for (n = 0; n < klninfo->status[dev].chipcount; n++) { + snprintf(one, sizeof(one), "%07d ", klninfo->devinfo[dev].chipstats[n + klninfo->status[dev].chipcount]); + strcat(data, one); + } root = api_add_string(root, buf, data, true); } } From 2dc54366f9e65cc2b1ea4b5d1ca8319697a3a2d9 Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 23 Sep 2013 20:16:15 +1000 Subject: [PATCH 27/31] klondike store and report errorcount and noise --- driver-klondike.c | 151 ++++++++++++++++++++++++++-------------------- 1 file changed, 86 insertions(+), 65 deletions(-) diff --git a/driver-klondike.c b/driver-klondike.c index 1be043a5..389444af 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -64,6 +64,7 @@ typedef struct klondike_status { uint8_t errorcount; uint16_t hashcount; uint16_t maxcount; + uint8_t noise; } WORKSTATUS; typedef struct _worktask { @@ -102,13 +103,15 @@ struct klondike_info { bool shutdown; pthread_rwlock_t stat_lock; struct thr_info replies_thr; - WORKSTATUS *status; + WORKSTATUS *status; DEVINFO *devinfo; WORKCFG *cfg; char *replies; int nextreply; int noncecount; uint64_t hashcount; + uint64_t errorcount; + uint64_t noisecount; }; IDENTITY KlondikeID; @@ -131,7 +134,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in int retries = CMD_REPLY_RETRIES; int chkreply = klninfo->nextreply; int sent, err; - + if (klncgpu->usbinfo.nodev) return NULL; @@ -157,7 +160,7 @@ static char *SendCmdGetReply(struct cgpu_info *klncgpu, char Cmd, int device, in } return NULL; } - + static bool klondike_get_stats(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); @@ -168,7 +171,7 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) applog(LOG_DEBUG, "Klondike getting status"); slaves = klninfo->status[0].slavecount; - + // loop thru devices and get status for each wr_lock(&(klninfo->stat_lock)); for (dev = 0; dev <= slaves; dev++) { @@ -177,9 +180,9 @@ static bool klondike_get_stats(struct cgpu_info *klncgpu) memcpy((void *)(&(klninfo->status[dev])), reply+2, sizeof(klninfo->status[dev])); } wr_unlock(&(klninfo->stat_lock)); - + // todo: detect slavecount change and realloc space - + return true; } @@ -187,15 +190,15 @@ static bool klondike_init(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int slaves, dev; - + char *reply = SendCmdGetReply(klncgpu, 'S', 0, 0, NULL); if (reply == NULL) return false; - + slaves = ((WORKSTATUS *)(reply+2))->slavecount; if (klninfo->status == NULL) { applog(LOG_DEBUG, "Klondike initializing data"); - + // alloc space for status, devinfo and cfg for master and slaves klninfo->status = calloc(slaves+1, sizeof(WORKSTATUS)); if (unlikely(!klninfo->status)) @@ -207,27 +210,27 @@ static bool klondike_init(struct cgpu_info *klncgpu) if (unlikely(!klninfo->cfg)) quit(1, "Failed to calloc cfg array in klondke_get_stats"); } - + WORKCFG cfgset = { 0,0,0,0,0 }; // zero init triggers read back only double temp1, temp2; int size = 2; - + if (opt_klondike_options != NULL) { // boundaries are checked by device, with valid values returned sscanf(opt_klondike_options, "%hu:%lf:%lf:%hhu", &cfgset.hashclock, &temp1, &temp2, &cfgset.fantarget); cfgset.temptarget = cvtCToKln(temp1); cfgset.tempcritical = cvtCToKln(temp2); cfgset.fantarget = (int)255*cfgset.fantarget/100; - size = sizeof(cfgset); + size = sizeof(cfgset); } - + for (dev = 0; dev <= slaves; dev++) { char *reply = SendCmdGetReply(klncgpu, 'C', dev, size, &cfgset); if (reply != NULL) { klninfo->cfg[dev] = *(WORKCFG *)(reply+2); - applog(LOG_NOTICE, "Klondike config (%d: Clk: %d, T:%.0lf, C:%.0lf, F:%d)", - dev, klninfo->cfg[dev].hashclock, - cvtKlnToC(klninfo->cfg[dev].temptarget), - cvtKlnToC(klninfo->cfg[dev].tempcritical), + applog(LOG_NOTICE, "Klondike config (%d: Clk: %d, T:%.0lf, C:%.0lf, F:%d)", + dev, klninfo->cfg[dev].hashclock, + cvtKlnToC(klninfo->cfg[dev].temptarget), + cvtKlnToC(klninfo->cfg[dev].tempcritical), (int)100*klninfo->cfg[dev].fantarget/256); } } @@ -236,9 +239,9 @@ static bool klondike_init(struct cgpu_info *klncgpu) klninfo->devinfo[dev].rangesize = ((uint64_t)1<<32) / klninfo->status[dev].chipcount; klninfo->devinfo[dev].chipstats = calloc(klninfo->status[dev].chipcount*2 , sizeof(uint32_t)); } - + SendCmdGetReply(klncgpu, 'E', 0, 1, "1"); - + return true; } @@ -249,23 +252,23 @@ static bool klondike_detect_one(struct libusb_device *dev, struct usb_find_devic if (unlikely(!klncgpu)) quit(1, "Failed to calloc klncgpu in klondike_detect_one"); - + klninfo = calloc(1, sizeof(*klninfo)); if (unlikely(!klninfo)) quit(1, "Failed to calloc klninfo in klondke_detect_one"); klncgpu->device_data = (FILE *)klninfo; - + klninfo->replies = calloc(MAX_REPLY_COUNT, REPLY_BUFSIZE); if (unlikely(!klninfo->replies)) quit(1, "Failed to calloc replies buffer in klondke_detect_one"); klninfo->nextreply = 0; - + if (usb_init(klncgpu, dev, found)) { - int attempts = 0; + int attempts = 0; while (attempts++ < 3) { char devpath[20], reply[REPLY_SIZE]; int sent, recd, err; - + sprintf(devpath, "%d:%d", (int)(klncgpu->usbinfo.bus_number), (int)(klncgpu->usbinfo.device_address)); err = usb_write(klncgpu, "I", 2, &sent, C_REQUESTRESULTS); if (err < 0 || sent != 2) { @@ -310,28 +313,28 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct work *work, *tmp; - + applog(LOG_DEBUG, "Klondike FOUND NONCE (%02x:%08x)", result->workid, result->nonce); HASH_ITER(hh, klncgpu->queued_work, work, tmp) { if (work->queued && (work->subid == (result->device*256 + result->workid))) { - + wr_lock(&(klninfo->stat_lock)); klninfo->devinfo[result->device].noncecount++; klninfo->noncecount++; wr_unlock(&(klninfo->stat_lock)); - + result->nonce = le32toh(result->nonce - 0xC0); applog(LOG_DEBUG, "Klondike SUBMIT NONCE (%02x:%08x)", result->workid, result->nonce); bool ok = submit_nonce(klncgpu->thr[0], work, result->nonce); - + applog(LOG_DEBUG, "Klondike chip stats %d, %08x, %d, %d", result->device, result->nonce, klninfo->devinfo[result->device].rangesize, klninfo->status[result->device].chipcount); klninfo->devinfo[result->device].chipstats[(result->nonce / klninfo->devinfo[result->device].rangesize) + (ok ? 0 : klninfo->status[result->device].chipcount)]++; return; } } - - applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - ignored", + + applog(LOG_ERR, "%s%i:%d unknown work (%02x:%08x) - ignored", klncgpu->drv->name, klncgpu->device_id, result->device, result->workid, result->nonce); //inc_hw_errors(klncgpu->thr[0]); } @@ -341,18 +344,19 @@ static void *klondike_get_replies(void *userdata) { struct cgpu_info *klncgpu = (struct cgpu_info *)userdata; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); + struct klondike_status *ks; char *replybuf; int err, recd; - applog(LOG_DEBUG, "Klondike listening for replies"); - + applog(LOG_DEBUG, "Klondike listening for replies"); + while (klninfo->shutdown == false) { if (klncgpu->usbinfo.nodev) return NULL; - + replybuf = klninfo->replies + klninfo->nextreply * REPLY_BUFSIZE; replybuf[0] = 0; - + err = usb_read(klncgpu, replybuf+1, REPLY_SIZE, &recd, C_GETRESULTS); if (!err && recd == REPLY_SIZE) { if (opt_log_level <= LOG_DEBUG) { @@ -362,10 +366,25 @@ static void *klondike_get_replies(void *userdata) } if (++klninfo->nextreply == MAX_REPLY_COUNT) klninfo->nextreply = 0; - + replybuf[0] = replybuf[1]; - if (replybuf[0] == '=') - klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); + switch (replybuf[0]) { + case '=': + klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); + break; + case 'S': + case 'W': + case 'A': + case 'E': + ks = (struct klondike_status *)(replybuf+1); + wr_lock(&(klninfo->stat_lock)); + klninfo->errorcount += ks->errorcount; + klninfo->noisecount += ks->noise; + wr_unlock(&(klninfo->stat_lock)); + break; + default: + break; + } } } return NULL; @@ -375,7 +394,7 @@ static void klondike_flush_work(struct cgpu_info *klncgpu) { struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int dev; - + applog(LOG_DEBUG, "Klondike flushing work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { char *reply = SendCmdGetReply(klncgpu, 'A', dev, 0, NULL); @@ -391,16 +410,16 @@ static bool klondike_thread_prepare(struct thr_info *thr) { struct cgpu_info *klncgpu = thr->cgpu; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); - + if (thr_info_create(&(klninfo->replies_thr), NULL, klondike_get_replies, (void *)klncgpu)) { applog(LOG_ERR, "%s%i: thread create failed", klncgpu->drv->name, klncgpu->device_id); return false; } pthread_detach(klninfo->replies_thr.pth); - + // let the listening get started cgsleep_ms(100); - + return klondike_init(klncgpu); } @@ -412,7 +431,7 @@ static bool klondike_thread_init(struct thr_info *thr) return false; klondike_flush_work(klncgpu); - + return true; } @@ -421,7 +440,7 @@ static void klondike_shutdown(struct thr_info *thr) struct cgpu_info *klncgpu = thr->cgpu; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int dev; - + applog(LOG_DEBUG, "Klondike shutting down work"); for (dev = 0; dev <= klninfo->status->slavecount; dev++) { SendCmdGetReply(klncgpu, 'E', dev, 1, "0"); @@ -435,7 +454,7 @@ static void klondike_thread_enable(struct thr_info *thr) if (klncgpu->usbinfo.nodev) return; - + //SendCmdGetReply(klncgpu, 'E', 0, 1, "0"); } @@ -445,29 +464,29 @@ static bool klondike_send_work(struct cgpu_info *klncgpu, int dev, struct work * struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct work *tmp; WORKTASK data; - + if (klncgpu->usbinfo.nodev) return false; - + memcpy(data.midstate, work->midstate, MIDSTATE_BYTES); memcpy(data.merkle, work->data + MERKLE_OFFSET, MERKLE_BYTES); data.workid = (uint8_t)(klninfo->devinfo[dev].nextworkid++ & 0xFF); work->subid = dev*256 + data.workid; - + if (opt_log_level <= LOG_DEBUG) { char *hexdata = bin2hex(&data.workid, sizeof(data)-3); applog(LOG_DEBUG, "WORKDATA: %s", hexdata); free(hexdata); } - + applog(LOG_DEBUG, "Klondike sending work (%d:%02x)", dev, data.workid); char *reply = SendCmdGetReply(klncgpu, 'W', dev, sizeof(data)-3, &data.workid); if (reply != NULL) { wr_lock(&(klninfo->stat_lock)); klninfo->status[dev] = *(WORKSTATUS *)(reply+2); wr_unlock(&(klninfo->stat_lock)); - - // remove old work + + // remove old work HASH_ITER(hh, klncgpu->queued_work, work, tmp) { if (work->queued && (work->subid == (int)(dev*256 + ((klninfo->devinfo[dev].nextworkid-2*MAX_WORK_COUNT) & 0xFF)))) work_completed(klncgpu, work); @@ -482,7 +501,7 @@ static bool klondike_queue_full(struct cgpu_info *klncgpu) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct work *work = NULL; int dev, queued; - + for (queued = 0; queued < MAX_WORK_COUNT-1; queued++) for (dev = 0; dev <= klninfo->status->slavecount; dev++) if (klninfo->status[dev].workqc <= queued) { @@ -495,7 +514,7 @@ static bool klondike_queue_full(struct cgpu_info *klncgpu) break; } } - + return true; } @@ -505,10 +524,10 @@ static int64_t klondike_scanwork(struct thr_info *thr) struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); int64_t newhashcount = 0; int dev; - + if (klncgpu->usbinfo.nodev) return -1; - + restart_wait(thr, 200); if (klninfo->status != NULL) { rd_lock(&(klninfo->stat_lock)); @@ -519,7 +538,7 @@ static int64_t klondike_scanwork(struct thr_info *thr) newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; klninfo->hashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; - + // todo: check stats for critical conditions } newhashcount += 0xffffffffull * (uint64_t)klninfo->noncecount; @@ -536,12 +555,12 @@ static void get_klondike_statline_before(char *buf, size_t siz, struct cgpu_info uint8_t temp = 0xFF; uint16_t fan = 0; int dev; - + if (klninfo->status == NULL) return; rd_lock(&(klninfo->stat_lock)); - for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { if (klninfo->status[dev].temp < temp) temp = klninfo->status[dev].temp; fan += klninfo->cfg[dev].fantarget; @@ -558,21 +577,21 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) struct api_data *root = NULL; char buf[32]; int dev; - + if (klninfo->status == NULL) return NULL; - + rd_lock(&(klninfo->stat_lock)); - for (dev = 0; dev <= klninfo->status->slavecount; dev++) { + for (dev = 0; dev <= klninfo->status->slavecount; dev++) { float fTemp = cvtKlnToC(klninfo->status[dev].temp); sprintf(buf, "Temp %d", dev); root = api_add_temp(root, buf, &fTemp, true); - + double dClk = (double)klninfo->cfg[dev].hashclock; sprintf(buf, "Clock %d", dev); root = api_add_freq(root, buf, &dClk, true); - + unsigned int iFan = (unsigned int)100 * klninfo->cfg[dev].fantarget / 255; sprintf(buf, "Fan Percent %d", dev); root = api_add_int(root, buf, (int *)(&iFan), true); @@ -582,7 +601,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) iFan = (unsigned int)TACH_FACTOR / klninfo->status[dev].fanspeed; sprintf(buf, "Fan RPM %d", dev); root = api_add_int(root, buf, (int *)(&iFan), true); - + if (klninfo->devinfo[dev].chipstats != NULL) { char data[2048]; char one[32]; @@ -595,7 +614,7 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) strcat(data, one); } root = api_add_string(root, buf, data, true); - + sprintf(buf, "Errors / Chip %d", dev); data[0] = '\0'; for (n = 0; n < klninfo->status[dev].chipcount; n++) { @@ -607,9 +626,11 @@ static struct api_data *klondike_api_stats(struct cgpu_info *klncgpu) } root = api_add_uint64(root, "Hash Count", &(klninfo->hashcount), true); + root = api_add_uint64(root, "Error Count", &(klninfo->errorcount), true); + root = api_add_uint64(root, "Noise Count", &(klninfo->noisecount), true); rd_unlock(&(klninfo->stat_lock)); - + return root; } From 5154e8472db081d15a1efa09d3853f654c5394a9 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 24 Sep 2013 12:46:09 +1000 Subject: [PATCH 28/31] klondike - avoid division by zero if maxcount is unexpectedly zero --- driver-klondike.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index 389444af..b3ffe37d 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -537,7 +537,8 @@ static int64_t klondike_scanwork(struct thr_info *thr) newhashdev += klninfo->status[dev].maxcount; // hash counter wrapped newhashdev += klninfo->status[dev].hashcount - klninfo->devinfo[dev].lasthashcount; klninfo->devinfo[dev].lasthashcount = klninfo->status[dev].hashcount; - klninfo->hashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; + if (klninfo->status[dev].maxcount != 0) + klninfo->hashcount += (newhashdev << 32) / klninfo->status[dev].maxcount; // todo: check stats for critical conditions } From 3b9e39fa99c942fb4a8bca0a9e4574ff99840309 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 24 Sep 2013 13:17:19 +1000 Subject: [PATCH 29/31] klondike - debug dump structured replies --- driver-klondike.c | 58 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/driver-klondike.c b/driver-klondike.c index b3ffe37d..44a62b28 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -82,7 +82,7 @@ typedef struct _workresult { uint32_t nonce; } WORKRESULT; -typedef struct kondike_cfg { +typedef struct klondike_cfg { uint16_t hashclock; uint8_t temptarget; uint8_t tempcritical; @@ -339,12 +339,18 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, WORKRESULT *result) //inc_hw_errors(klncgpu->thr[0]); } +// Change this to LOG_WARNING if you wish to always see the replies +#define READ_DEBUG LOG_DEBUG + // thread to keep looking for replies static void *klondike_get_replies(void *userdata) { struct cgpu_info *klncgpu = (struct cgpu_info *)userdata; struct klondike_info *klninfo = (struct klondike_info *)(klncgpu->device_data); struct klondike_status *ks; + struct _workresult *wr; + struct klondike_cfg *kc; + struct klondike_id *ki; char *replybuf; int err, recd; @@ -361,7 +367,7 @@ static void *klondike_get_replies(void *userdata) if (!err && recd == REPLY_SIZE) { if (opt_log_level <= LOG_DEBUG) { char *hexdata = bin2hex((unsigned char *)(replybuf+1), recd); - applog(LOG_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); + applog(READ_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); free(hexdata); } if (++klninfo->nextreply == MAX_REPLY_COUNT) @@ -370,7 +376,16 @@ static void *klondike_get_replies(void *userdata) replybuf[0] = replybuf[1]; switch (replybuf[0]) { case '=': + wr = (struct _workresult *)(replybuf+1); klondike_check_nonce(klncgpu, (WORKRESULT *)replybuf); + applog(READ_DEBUG, + "%s (%s) reply: work [%c] device=%d workid=%d" + " nonce=0x%08x", + klncgpu->drv->dname, klncgpu->device_path, + *(replybuf+1), + (int)(wr->device), + (int)(wr->workid), + (unsigned int)(wr->nonce)); break; case 'S': case 'W': @@ -381,6 +396,45 @@ static void *klondike_get_replies(void *userdata) klninfo->errorcount += ks->errorcount; klninfo->noisecount += ks->noise; wr_unlock(&(klninfo->stat_lock)); + applog(READ_DEBUG, + "%s (%s) reply: status [%c] chips=%d slaves=%d" + " workcq=%d workid=%d temp=%d fan=%d errors=%d" + " hashes=%d max=%d noise=%d", + klncgpu->drv->dname, klncgpu->device_path, + *(replybuf+1), + (int)(ks->chipcount), + (int)(ks->slavecount), + (int)(ks->workqc), + (int)(ks->workid), + (int)(ks->temp), + (int)(ks->fanspeed), + (int)(ks->errorcount), + (int)(ks->hashcount), + (int)(ks->maxcount), + (int)(ks->noise)); + break; + case 'C': + kc = (struct klondike_cfg *)(replybuf+2); + applog(READ_DEBUG, + "%s (%s) reply: config [%c] clock=%d temptarget=%d" + " tempcrit=%d fan=%d", + klncgpu->drv->dname, klncgpu->device_path, + *(replybuf+1), + (int)(kc->hashclock), + (int)(kc->temptarget), + (int)(kc->tempcritical), + (int)(kc->fantarget)); + break; + case 'I': + ki = (struct klondike_id *)(replybuf+2); + applog(READ_DEBUG, + "%s (%s) reply: info [%c] version=0x%02x prod=%.7s" + " serial=0x%08x", + klncgpu->drv->dname, klncgpu->device_path, + *(replybuf+1), + (int)(ki->version), + ki->product, + (unsigned int)(ki->serial)); break; default: break; From f300171c5b54734954e26e791b0fdcafd378d737 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 24 Sep 2013 13:23:12 +1000 Subject: [PATCH 30/31] klondike - correct 1st reply debug based on define --- driver-klondike.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index 44a62b28..b9189c60 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -365,7 +365,7 @@ static void *klondike_get_replies(void *userdata) err = usb_read(klncgpu, replybuf+1, REPLY_SIZE, &recd, C_GETRESULTS); if (!err && recd == REPLY_SIZE) { - if (opt_log_level <= LOG_DEBUG) { + if (opt_log_level <= READ_DEBUG) { char *hexdata = bin2hex((unsigned char *)(replybuf+1), recd); applog(READ_DEBUG, "%s (%s) reply [%s:%s]", klncgpu->drv->dname, klncgpu->device_path, replybuf+1, hexdata); free(hexdata); From 2270a932ea2b1efa606fe12fef9eeaa4311e3f80 Mon Sep 17 00:00:00 2001 From: Kano Date: Thu, 26 Sep 2013 12:24:13 +1000 Subject: [PATCH 31/31] klondike correct cvtKlnToC() temperature calculation --- driver-klondike.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/driver-klondike.c b/driver-klondike.c index b9189c60..797ee377 100644 --- a/driver-klondike.c +++ b/driver-klondike.c @@ -118,7 +118,17 @@ IDENTITY KlondikeID; static double cvtKlnToC(uint8_t temp) { - return (double)1/((double)1/(25+273.15) + log((double)temp*1000/(256-temp)/2200)/3987) - 273.15; + double Rt, stein, celsius; + + Rt = 1000.0 * 255.0 / (double)temp - 1000.0; + + stein = log(Rt / 2200.0) / 3987.0; + + stein += 1.0 / (double)(25.0 + 273.15); + + celsius = (1.0 / stein) - 273.15; + + return celsius; } static int cvtCToKln(double deg)