From b3ae0f168e10c4ee0371e22788a014f387e51b67 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 31 Mar 2013 21:54:32 +1100 Subject: [PATCH 1/4] find_work() to find work in devices work queue --- cgminer.c | 18 ++++++++++++++++++ miner.h | 1 + 2 files changed, 19 insertions(+) diff --git a/cgminer.c b/cgminer.c index f48082a8..5a4d45b7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5786,6 +5786,24 @@ struct work *get_queued(struct cgpu_info *cgpu) return ret; } +struct work *find_work(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen) +{ + struct work *work, *tmp, *ret = NULL; + + rd_lock(&cgpu->qlock); + HASH_ITER(hh, cgpu->queued_work, work, tmp) { + if (work->queued && + memcmp(work->midstate, midstate, midstatelen) == 0 && + memcmp(work->data + offset, data, datalen) == 0) { + ret = work; + break; + } + } + rd_unlock(&cgpu->qlock); + + return ret; +} + /* This function should be used by queued device drivers when they're sure * the work struct is no longer in use. */ void work_completed(struct cgpu_info *cgpu, struct work *work) diff --git a/miner.h b/miner.h index b3ac3ae5..ca38cc89 100644 --- a/miner.h +++ b/miner.h @@ -1183,6 +1183,7 @@ struct modminer_fpga_state { extern void get_datestamp(char *, struct timeval *); extern void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern struct work *get_queued(struct cgpu_info *cgpu); +extern struct work *find_work(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void work_completed(struct cgpu_info *cgpu, struct work *work); extern void hash_queued_work(struct thr_info *mythr); extern void tailsprintf(char *f, const char *fmt, ...); From 8dd1ed24542720640ace964b214be7d7a4b68288 Mon Sep 17 00:00:00 2001 From: Kano Date: Sun, 31 Mar 2013 21:58:48 +1100 Subject: [PATCH 2/4] usbutils extra message requirements --- usbutils.c | 29 +++++++++++++++++++++++++++++ usbutils.h | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/usbutils.c b/usbutils.c index 13941477..69bd72ec 100644 --- a/usbutils.c +++ b/usbutils.c @@ -195,6 +195,8 @@ extern struct device_drv avalon_drv; #define STRBUFLEN 256 static const char *BLANK = ""; +static const char *space = " "; +static const char *nodatareturned = "no data returned "; // For device limits by driver static struct driver_count { @@ -286,6 +288,12 @@ static const char *C_PURGETX_S = "PurgeTx"; static const char *C_FLASHREPLY_S = "FlashReply"; static const char *C_REQUESTDETAILS_S = "RequestDetails"; static const char *C_GETDETAILS_S = "GetDetails"; +static const char *C_REQUESTRESULTS_S = "RequestResults"; +static const char *C_GETRESULTS_S = "GetResults"; +static const char *C_REQUESTQUEJOB_S = "RequestQueJob"; +static const char *C_REQUESTQUEJOBSTATUS_S = "RequestQueJobStatus"; +static const char *C_QUEJOB_S = "QueJob"; +static const char *C_QUEJOBSTATUS_S = "QueJobStatus"; #ifdef EOL #undef EOL @@ -745,6 +753,12 @@ static void cgusb_check_init() usb_commands[C_FLASHREPLY] = C_FLASHREPLY_S; usb_commands[C_REQUESTDETAILS] = C_REQUESTDETAILS_S; usb_commands[C_GETDETAILS] = C_GETDETAILS_S; + usb_commands[C_REQUESTRESULTS] = C_REQUESTRESULTS_S; + usb_commands[C_GETRESULTS] = C_GETRESULTS_S; + usb_commands[C_REQUESTQUEJOB] = C_REQUESTQUEJOB_S; + usb_commands[C_REQUESTQUEJOBSTATUS] = C_REQUESTQUEJOBSTATUS_S; + usb_commands[C_QUEJOB] = C_QUEJOB_S; + usb_commands[C_QUEJOBSTATUS] = C_QUEJOBSTATUS_S; stats_initialised = true; } @@ -759,6 +773,21 @@ const char *usb_cmdname(enum usb_cmds cmd) return usb_commands[cmd]; } +void usb_applog(struct cgpu_info *cgpu, enum usb_cmds cmd, char *msg, int amount, int err) +{ + if (msg && !*msg) + msg = NULL; + + if (!msg && amount == 0 && err == LIBUSB_SUCCESS) + msg = (char *)nodatareturned; + + applog(LOG_ERR, "%s%i: %s failed%s%s (err=%d amt%d)", + cgpu->drv->name, cgpu->device_id, + usb_cmdname(cmd), + msg ? space : BLANK, msg ? msg : BLANK, + err, amount); +} + #ifndef WIN32 #include #include diff --git a/usbutils.h b/usbutils.h index 7cacc43a..8e34d817 100644 --- a/usbutils.h +++ b/usbutils.h @@ -125,6 +125,12 @@ enum usb_cmds { C_FLASHREPLY, C_REQUESTDETAILS, C_GETDETAILS, + C_REQUESTRESULTS, + C_GETRESULTS, + C_REQUESTQUEJOB, + C_REQUESTQUEJOBSTATUS, + C_QUEJOB, + C_QUEJOBSTATUS, C_MAX }; @@ -133,6 +139,7 @@ struct cgpu_info; void usb_all(int level); const char *usb_cmdname(enum usb_cmds cmd); +void usb_applog(struct cgpu_info *bflsc, enum usb_cmds cmd, char *msg, int amount, int err); void usb_uninit(struct cgpu_info *cgpu); bool usb_init(struct cgpu_info *cgpu, struct libusb_device *dev, struct usb_find_devices *found); void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_device *, struct usb_find_devices *)); From 131e20042a4fe082fefb40a9ed434c17f4f9da5e Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 1 Apr 2013 00:35:50 +1100 Subject: [PATCH 3/4] functions for handling work queues --- cgminer.c | 40 +++++++++++++++++++++++++++++++++++++--- miner.h | 5 ++++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/cgminer.c b/cgminer.c index 5a4d45b7..7d5738d8 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5786,12 +5786,32 @@ struct work *get_queued(struct cgpu_info *cgpu) return ret; } -struct work *find_work(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen) +/* This function is for including work in the given que hashtable. + * The calling function must lock access to the que if it is required. */ +struct work *add_to_work_que(struct work *que, struct work *work) +{ + HASH_ADD_INT(que, id, work); + return que; +} + +/* This function is for removing work from the given que hashtable. + * The calling function must lock access to the que if it is required. */ +struct work *del_from_work_que(struct work *que, struct work *work) +{ + HASH_DEL(que, work); + return que; +} + +/* This function is for finding an already queued work item in the + * given que hashtable. Code using this function must be able + * to handle NULL as a return which implies there is no matching work. + * The calling function must lock access to the que if it is required. + * The common values for midstatelen, offset, datalen are 32, 64, 12 */ +struct work *find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen) { struct work *work, *tmp, *ret = NULL; - rd_lock(&cgpu->qlock); - HASH_ITER(hh, cgpu->queued_work, work, tmp) { + HASH_ITER(hh, que, work, tmp) { if (work->queued && memcmp(work->midstate, midstate, midstatelen) == 0 && memcmp(work->data + offset, data, datalen) == 0) { @@ -5799,6 +5819,20 @@ struct work *find_work(struct cgpu_info *cgpu, char *midstate, size_t midstatele break; } } + + return ret; +} + +/* This function is for finding an already queued work item in the + * device's queued_work hashtable. Code using this function must be able + * to handle NULL as a return which implies there is no matching work. + * The common values for midstatelen, offset, datalen are 32, 64, 12 */ +struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen) +{ + struct work *ret; + + rd_lock(&cgpu->qlock); + ret = find_work_bymidstate(cgpu->queued_work, midstate, midstatelen, data, offset, datalen); rd_unlock(&cgpu->qlock); return ret; diff --git a/miner.h b/miner.h index ca38cc89..e2b4039b 100644 --- a/miner.h +++ b/miner.h @@ -1183,7 +1183,10 @@ struct modminer_fpga_state { extern void get_datestamp(char *, struct timeval *); extern void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern struct work *get_queued(struct cgpu_info *cgpu); -extern struct work *find_work(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); +extern struct work *add_to_work_que(struct work *que, struct work *work); +extern struct work *del_from_work_que(struct work *que, struct work *work); +extern struct work *find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); +struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void work_completed(struct cgpu_info *cgpu, struct work *work); extern void hash_queued_work(struct thr_info *mythr); extern void tailsprintf(char *f, const char *fmt, ...); From 73616fb810a76bd6b2e97b7b14438622bb4756bc Mon Sep 17 00:00:00 2001 From: Kano Date: Mon, 1 Apr 2013 00:38:19 +1100 Subject: [PATCH 4/4] miner.h missing extern --- miner.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miner.h b/miner.h index e2b4039b..0595f945 100644 --- a/miner.h +++ b/miner.h @@ -1186,7 +1186,7 @@ extern struct work *get_queued(struct cgpu_info *cgpu); extern struct work *add_to_work_que(struct work *que, struct work *work); extern struct work *del_from_work_que(struct work *que, struct work *work); extern struct work *find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); -struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); +extern struct work *find_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern void work_completed(struct cgpu_info *cgpu, struct work *work); extern void hash_queued_work(struct thr_info *mythr); extern void tailsprintf(char *f, const char *fmt, ...);