1
0
mirror of https://github.com/GOSTSec/sgminer synced 2025-01-11 07:17:58 +00:00

Merge branch 'master' into libusbx

This commit is contained in:
Con Kolivas 2013-10-13 15:54:32 +11:00
commit 9d29e0940a
7 changed files with 122 additions and 58 deletions

View File

@ -3218,8 +3218,6 @@ static void __kill_work(void)
/* Release USB resources in case it's a restart /* Release USB resources in case it's a restart
* and not a QUIT */ * and not a QUIT */
if (!opt_scrypt) { if (!opt_scrypt) {
usb_polling = false;
applog(LOG_DEBUG, "Releasing all USB devices"); applog(LOG_DEBUG, "Releasing all USB devices");
usb_cleanup(); usb_cleanup();
@ -4006,15 +4004,15 @@ static void set_blockdiff(const struct work *work)
static bool test_work_current(struct work *work) static bool test_work_current(struct work *work)
{ {
bool ret = true; bool ret = true;
char *hexstr; char hexstr[20];
if (work->mandatory) if (work->mandatory)
return ret; return ret;
/* Hack to work around dud work sneaking into test */ /* Hack to work around dud work sneaking into test */
hexstr = bin2hex(work->data + 8, 18); __bin2hex(hexstr, work->data + 8, 18);
if (!strncmp(hexstr, "000000000000000000000000000000000000", 36)) if (!strncmp(hexstr, "000000000000000000000000000000000000", 36))
goto out_free; return ret;
/* Search to see if this block exists yet and if not, consider it a /* Search to see if this block exists yet and if not, consider it a
* new block and set the current block details to this one */ * new block and set the current block details to this one */
@ -4049,7 +4047,7 @@ static bool test_work_current(struct work *work)
applog(LOG_DEBUG, "Deleted block %d from database", deleted_block); applog(LOG_DEBUG, "Deleted block %d from database", deleted_block);
set_curblock(hexstr, work->data); set_curblock(hexstr, work->data);
if (unlikely(new_blocks == 1)) if (unlikely(new_blocks == 1))
goto out_free; return ret;
work->work_block = ++work_block; work->work_block = ++work_block;
@ -4072,8 +4070,6 @@ static bool test_work_current(struct work *work)
} }
} }
work->longpoll = false; work->longpoll = false;
out_free:
free(hexstr);
return ret; return ret;
} }
@ -5467,8 +5463,8 @@ static void *stratum_sthread(void *userdata)
quit(1, "Failed to create stratum_q in stratum_sthread"); quit(1, "Failed to create stratum_q in stratum_sthread");
while (42) { while (42) {
char noncehex[12], nonce2hex[20];
struct stratum_share *sshare; struct stratum_share *sshare;
char *noncehex, *nonce2hex;
uint32_t *hash32, nonce; uint32_t *hash32, nonce;
char s[1024], nonce2[8]; char s[1024], nonce2[8];
struct work *work; struct work *work;
@ -5497,7 +5493,7 @@ static void *stratum_sthread(void *userdata)
/* This work item is freed in parse_stratum_response */ /* This work item is freed in parse_stratum_response */
sshare->work = work; sshare->work = work;
nonce = *((uint32_t *)(work->data + 76)); nonce = *((uint32_t *)(work->data + 76));
noncehex = bin2hex((const unsigned char *)&nonce, 4); __bin2hex(noncehex, (const unsigned char *)&nonce, 4);
memset(s, 0, 1024); memset(s, 0, 1024);
mutex_lock(&sshare_lock); mutex_lock(&sshare_lock);
@ -5508,15 +5504,11 @@ static void *stratum_sthread(void *userdata)
memset(nonce2, 0, 8); memset(nonce2, 0, 8);
/* We only use uint32_t sized nonce2 increments internally */ /* We only use uint32_t sized nonce2 increments internally */
memcpy(nonce2, &work->nonce2, sizeof(uint32_t)); memcpy(nonce2, &work->nonce2, sizeof(uint32_t));
nonce2hex = bin2hex((const unsigned char *)nonce2, work->nonce2_len); __bin2hex(nonce2hex, (const unsigned char *)nonce2, work->nonce2_len);
if (unlikely(!nonce2hex))
quit(1, "Failed to bin2hex nonce2 in stratum_thread");
snprintf(s, sizeof(s), snprintf(s, sizeof(s),
"{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}", "{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
pool->rpc_user, work->job_id, nonce2hex, work->ntime, noncehex, sshare->id); pool->rpc_user, work->job_id, nonce2hex, work->ntime, noncehex, sshare->id);
free(noncehex);
free(nonce2hex);
applog(LOG_INFO, "Submitting share %08lx to pool %d", applog(LOG_INFO, "Submitting share %08lx to pool %d",
(long unsigned int)htole32(hash32[6]), pool->pool_no); (long unsigned int)htole32(hash32[6]), pool->pool_no);
@ -5974,7 +5966,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
cgtime(&work->tv_staged); cgtime(&work->tv_staged);
} }
static struct work *get_work(struct thr_info *thr, const int thr_id) struct work *get_work(struct thr_info *thr, const int thr_id)
{ {
struct work *work = NULL; struct work *work = NULL;
@ -6532,6 +6524,53 @@ void hash_queued_work(struct thr_info *mythr)
cgpu->deven = DEV_DISABLED; cgpu->deven = DEV_DISABLED;
} }
/* This version of hash_work is for devices drivers that want to do their own
* work management entirely, usually by using get_work(). Note that get_work
* is a blocking function and will wait indefinitely if no work is available
* so this must be taken into consideration in the driver. */
void hash_driver_work(struct thr_info *mythr)
{
struct timeval tv_start = {0, 0}, tv_end;
struct cgpu_info *cgpu = mythr->cgpu;
struct device_drv *drv = cgpu->drv;
const int thr_id = mythr->id;
int64_t hashes_done = 0;
while (likely(!cgpu->shutdown)) {
struct timeval diff;
int64_t hashes;
mythr->work_restart = false;
hashes = drv->scanwork(mythr);
if (unlikely(hashes == -1 )) {
applog(LOG_ERR, "%s %d failure, disabling!", drv->name, cgpu->device_id);
cgpu->deven = DEV_DISABLED;
dev_error(cgpu, REASON_THREAD_ZERO_HASH);
mt_disable(mythr, thr_id, drv);
}
hashes_done += hashes;
cgtime(&tv_end);
timersub(&tv_end, &tv_start, &diff);
/* Update the hashmeter at most 5 times per second */
if ((hashes_done && (diff.tv_sec > 0 || diff.tv_usec > 200000)) ||
diff.tv_sec >= opt_log_interval) {
hashmeter(thr_id, &diff, hashes_done);
hashes_done = 0;
copy_time(&tv_start, &tv_end);
}
if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED))
mt_disable(mythr, thr_id, drv);
if (unlikely(mythr->work_restart))
drv->flush_work(cgpu);
}
cgpu->deven = DEV_DISABLED;
}
void *miner_thread(void *userdata) void *miner_thread(void *userdata)
{ {
struct thr_info *mythr = userdata; struct thr_info *mythr = userdata;
@ -7180,6 +7219,8 @@ static void clean_up(void)
clear_adl(nDevs); clear_adl(nDevs);
#endif #endif
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
usb_polling = false;
pthread_join(usb_poll_thread, NULL);
libusb_exit(NULL); libusb_exit(NULL);
#endif #endif
@ -7751,11 +7792,12 @@ static void probe_pools(void)
#ifdef USE_USBUTILS #ifdef USE_USBUTILS
static void *libusb_poll_thread(void __maybe_unused *arg) static void *libusb_poll_thread(void __maybe_unused *arg)
{ {
struct timeval tv_end = {0, 200000};
RenameThread("usbpoll"); RenameThread("usbpoll");
pthread_detach(pthread_self());
while (usb_polling) while (usb_polling)
libusb_handle_events(NULL); libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
return NULL; return NULL;
} }

View File

@ -220,18 +220,24 @@ static bool bitfury_checkresults(struct thr_info *thr, struct work *work, uint32
return false; return false;
} }
static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work, static int64_t bitfury_scanwork(struct thr_info *thr)
int64_t __maybe_unused max_nonce)
{ {
struct cgpu_info *bitfury = thr->cgpu; struct cgpu_info *bitfury = thr->cgpu;
struct bitfury_info *info = bitfury->device_data; struct bitfury_info *info = bitfury->device_data;
struct timeval tv_now; struct timeval tv_now;
struct work *work;
double nonce_rate; double nonce_rate;
int64_t ret = 0; int64_t ret = 0;
int amount, i; int amount, i;
char buf[45]; char buf[45];
int ms_diff; int ms_diff;
work = get_work(thr, thr->id);
if (unlikely(thr->work_restart)) {
free_work(work);
return 0;
}
buf[0] = 'W'; buf[0] = 'W';
memcpy(buf + 1, work->midstate, 32); memcpy(buf + 1, work->midstate, 32);
memcpy(buf + 33, work->data + 64, 12); memcpy(buf + 33, work->data + 64, 12);
@ -298,8 +304,7 @@ static int64_t bitfury_scanhash(struct thr_info *thr, struct work *work,
cascade: cascade:
for (i = BF1ARRAY_SIZE; i > 0; i--) for (i = BF1ARRAY_SIZE; i > 0; i--)
info->prevwork[i] = info->prevwork[i - 1]; info->prevwork[i] = info->prevwork[i - 1];
info->prevwork[0] = copy_work(work); info->prevwork[0] = work;
work->blk.nonce = 0xffffffff;
info->cycles++; info->cycles++;
info->total_nonces += info->nonces; info->total_nonces += info->nonces;
@ -358,7 +363,8 @@ struct device_drv bitfury_drv = {
.dname = "bitfury", .dname = "bitfury",
.name = "BF1", .name = "BF1",
.drv_detect = bitfury_detect, .drv_detect = bitfury_detect,
.scanhash = bitfury_scanhash, .hash_work = &hash_driver_work,
.scanwork = bitfury_scanwork,
.get_api_stats = bitfury_api_stats, .get_api_stats = bitfury_api_stats,
.reinit_device = bitfury_init, .reinit_device = bitfury_init,
.thread_shutdown = bitfury_shutdown, .thread_shutdown = bitfury_shutdown,

View File

@ -952,6 +952,7 @@ extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
#endif #endif
extern const char *proxytype(proxytypes_t proxytype); extern const char *proxytype(proxytypes_t proxytype);
extern char *get_proxy(char *url, struct pool *pool); extern char *get_proxy(char *url, struct pool *pool);
extern void __bin2hex(char *s, const unsigned char *p, size_t len);
extern char *bin2hex(const unsigned char *p, size_t len); extern char *bin2hex(const unsigned char *p, size_t len);
extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);
@ -1384,12 +1385,14 @@ extern void submit_tested_work(struct thr_info *thr, struct work *work);
extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); extern bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce);
extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce, extern bool submit_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
int noffset); int noffset);
extern struct work *get_work(struct thr_info *thr, const int thr_id);
extern struct work *get_queued(struct cgpu_info *cgpu); extern struct work *get_queued(struct cgpu_info *cgpu);
extern struct work *__find_work_bymidstate(struct work *que, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern struct work *__find_work_bymidstate(struct work *que, 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 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 *clone_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern struct work *clone_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 work_completed(struct cgpu_info *cgpu, struct work *work);
extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen); extern struct work *take_queued_work_bymidstate(struct cgpu_info *cgpu, char *midstate, size_t midstatelen, char *data, int offset, size_t datalen);
extern void hash_driver_work(struct thr_info *mythr);
extern void hash_queued_work(struct thr_info *mythr); extern void hash_queued_work(struct thr_info *mythr);
extern void _wlog(const char *str); extern void _wlog(const char *str);
extern void _wlogprint(const char *str); extern void _wlogprint(const char *str);

12
ocl.c
View File

@ -342,6 +342,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
/* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */ /* Check for OpenCL >= 1.0 support, needed for global offset parameter usage. */
char * devoclver = malloc(1024); char * devoclver = malloc(1024);
const char * ocl10 = "OpenCL 1.0"; const char * ocl10 = "OpenCL 1.0";
const char * ocl11 = "OpenCL 1.1";
status = clGetDeviceInfo(devices[gpu], CL_DEVICE_VERSION, 1024, (void *)devoclver, NULL); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_VERSION, 1024, (void *)devoclver, NULL);
if (status != CL_SUCCESS) { if (status != CL_SUCCESS) {
@ -349,8 +350,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
return NULL; return NULL;
} }
find = strstr(devoclver, ocl10); find = strstr(devoclver, ocl10);
if (!find) if (!find) {
clState->hasOpenCL11plus = true; clState->hasOpenCL11plus = true;
find = strstr(devoclver, ocl11);
if (!find)
clState->hasOpenCL12plus = true;
}
status = clGetDeviceInfo(devices[gpu], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), (void *)&preferred_vwidth, NULL); status = clGetDeviceInfo(devices[gpu], CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), (void *)&preferred_vwidth, NULL);
if (status != CL_SUCCESS) { if (status != CL_SUCCESS) {
@ -618,7 +623,8 @@ build:
if (clState->hasBitAlign) { if (clState->hasBitAlign) {
strcat(CompilerOptions, " -D BITALIGN"); strcat(CompilerOptions, " -D BITALIGN");
applog(LOG_DEBUG, "cl_amd_media_ops found, setting BITALIGN"); applog(LOG_DEBUG, "cl_amd_media_ops found, setting BITALIGN");
if (strstr(name, "Cedar") || if (!clState->hasOpenCL12plus &&
(strstr(name, "Cedar") ||
strstr(name, "Redwood") || strstr(name, "Redwood") ||
strstr(name, "Juniper") || strstr(name, "Juniper") ||
strstr(name, "Cypress" ) || strstr(name, "Cypress" ) ||
@ -630,7 +636,7 @@ build:
strstr(name, "Antilles" ) || strstr(name, "Antilles" ) ||
strstr(name, "Wrestler" ) || strstr(name, "Wrestler" ) ||
strstr(name, "Zacate" ) || strstr(name, "Zacate" ) ||
strstr(name, "WinterPark" )) strstr(name, "WinterPark" )))
patchbfi = true; patchbfi = true;
} else } else
applog(LOG_DEBUG, "cl_amd_media_ops not found, will not set BITALIGN"); applog(LOG_DEBUG, "cl_amd_media_ops not found, will not set BITALIGN");

1
ocl.h
View File

@ -27,6 +27,7 @@ typedef struct {
#endif #endif
bool hasBitAlign; bool hasBitAlign;
bool hasOpenCL11plus; bool hasOpenCL11plus;
bool hasOpenCL12plus;
bool goffset; bool goffset;
cl_uint vwidth; cl_uint vwidth;
size_t max_work_size; size_t max_work_size;

View File

@ -2245,7 +2245,6 @@ static int callback_wait(struct usb_transfer *ut, int *transferred, unsigned int
/* No need to sort out mutexes here since they won't be reused */ /* No need to sort out mutexes here since they won't be reused */
*transferred = transfer->actual_length; *transferred = transfer->actual_length;
libusb_free_transfer(transfer);
return ret; return ret;
} }
@ -2296,6 +2295,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
errn = errno; errn = errno;
if (!err) if (!err)
err = callback_wait(&ut, transferred, timeout); err = callback_wait(&ut, transferred, timeout);
libusb_free_transfer(ut.transfer);
STATS_TIMEVAL(&tv_finish); STATS_TIMEVAL(&tv_finish);
USB_STATS(cgpu, &tv_start, &tv_finish, err, mode, cmd, seq, timeout); USB_STATS(cgpu, &tv_start, &tv_finish, err, mode, cmd, seq, timeout);
@ -2712,12 +2712,9 @@ static int usb_control_transfer(libusb_device_handle *dev_handle, uint8_t bmRequ
unsigned char *buffer, uint16_t wLength, unsigned int timeout) unsigned char *buffer, uint16_t wLength, unsigned int timeout)
{ {
struct usb_transfer ut; struct usb_transfer ut;
unsigned char buf[70];
int err, transferred; int err, transferred;
unsigned char *buf;
buf = malloc(70);
if (unlikely(!buf))
quit(1, "Failed to malloc buf in usb_control_transfer");
init_usb_transfer(&ut); init_usb_transfer(&ut);
mutex_lock(&ut.mutex); mutex_lock(&ut.mutex);
libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue, libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue,
@ -2731,10 +2728,13 @@ static int usb_control_transfer(libusb_device_handle *dev_handle, uint8_t bmRequ
unsigned char *ofbuf = libusb_control_transfer_get_data(ut.transfer); unsigned char *ofbuf = libusb_control_transfer_get_data(ut.transfer);
memcpy(buffer, ofbuf, transferred); memcpy(buffer, ofbuf, transferred);
return transferred; err = transferred;
goto out;
} }
if ((err) == LIBUSB_TRANSFER_CANCELLED) if ((err) == LIBUSB_TRANSFER_CANCELLED)
err = LIBUSB_ERROR_TIMEOUT; err = LIBUSB_ERROR_TIMEOUT;
out:
libusb_free_transfer(ut.transfer);
return err; return err;
} }
@ -2812,21 +2812,22 @@ out_:
return err; return err;
} }
/* We use the write devlock for control transfers since some control transfers
* are rare but may be changing settings within the device causing problems
* if concurrent transfers are happening. Using the write lock serialises
* any transfers. */
int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd) int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint32_t *data, int siz, unsigned int timeout, enum usb_cmds cmd)
{ {
int pstate, err; int pstate, err;
DEVRLOCK(cgpu, pstate); DEVWLOCK(cgpu, pstate);
err = __usb_transfer(cgpu, request_type, bRequest, wValue, wIndex, data, siz, timeout, cmd); err = __usb_transfer(cgpu, request_type, bRequest, wValue, wIndex, data, siz, timeout, cmd);
if (NOCONTROLDEV(err)) { if (NOCONTROLDEV(err))
cg_ruwlock(&cgpu->usbinfo.devlock);
release_cgpu(cgpu); release_cgpu(cgpu);
cg_dwlock(&cgpu->usbinfo.devlock);
}
DEVRUNLOCK(cgpu, pstate); DEVWUNLOCK(cgpu, pstate);
return err; return err;
} }
@ -2840,7 +2841,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
unsigned char tbuf[64]; unsigned char tbuf[64];
int err, pstate; int err, pstate;
DEVRLOCK(cgpu, pstate); DEVWLOCK(cgpu, pstate);
USBDEBUG("USB debug: _usb_transfer_read(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",bufsiz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, bufsiz, timeout, usb_cmdname(cmd)); USBDEBUG("USB debug: _usb_transfer_read(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",bufsiz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, bufsiz, timeout, usb_cmdname(cmd));
@ -2896,13 +2897,10 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
err, libusb_error_name(err)); err, libusb_error_name(err));
} }
out_noerrmsg: out_noerrmsg:
if (NOCONTROLDEV(err)) { if (NOCONTROLDEV(err))
cg_ruwlock(&cgpu->usbinfo.devlock);
release_cgpu(cgpu); release_cgpu(cgpu);
cg_dwlock(&cgpu->usbinfo.devlock);
}
DEVRUNLOCK(cgpu, pstate); DEVWUNLOCK(cgpu, pstate);
return err; return err;
} }

14
util.c
View File

@ -584,6 +584,16 @@ char *get_proxy(char *url, struct pool *pool)
return url; return url;
} }
/* Adequate size s==len*2 + 1 must be alloced to use this variant */
void __bin2hex(char *s, const unsigned char *p, size_t len)
{
int i;
for (i = 0; i < (int)len; i++)
sprintf(s + (i * 2), "%02x", (unsigned int)p[i]);
}
/* Returns a malloced array string of a binary value of arbitrary length. The /* Returns a malloced array string of a binary value of arbitrary length. The
* array is rounded up to a 4 byte size to appease architectures that need * array is rounded up to a 4 byte size to appease architectures that need
* aligned array sizes */ * aligned array sizes */
@ -591,7 +601,6 @@ char *bin2hex(const unsigned char *p, size_t len)
{ {
ssize_t slen; ssize_t slen;
char *s; char *s;
int i;
slen = len * 2 + 1; slen = len * 2 + 1;
if (slen % 4) if (slen % 4)
@ -600,8 +609,7 @@ char *bin2hex(const unsigned char *p, size_t len)
if (unlikely(!s)) if (unlikely(!s))
quithere(1, "Failed to calloc"); quithere(1, "Failed to calloc");
for (i = 0; i < (int)len; i++) __bin2hex(s, p, len);
sprintf(s + (i * 2), "%02x", (unsigned int)p[i]);
return s; return s;
} }