Browse Source

Merge branch 'master' into libusbx

nfactor-troky
Con Kolivas 11 years ago
parent
commit
9d29e0940a
  1. 78
      cgminer.c
  2. 16
      driver-bitfury.c
  3. 3
      miner.h
  4. 34
      ocl.c
  5. 1
      ocl.h
  6. 34
      usbutils.c
  7. 14
      util.c

78
cgminer.c

@ -3218,8 +3218,6 @@ static void __kill_work(void) @@ -3218,8 +3218,6 @@ static void __kill_work(void)
/* Release USB resources in case it's a restart
* and not a QUIT */
if (!opt_scrypt) {
usb_polling = false;
applog(LOG_DEBUG, "Releasing all USB devices");
usb_cleanup();
@ -4006,15 +4004,15 @@ static void set_blockdiff(const struct work *work) @@ -4006,15 +4004,15 @@ static void set_blockdiff(const struct work *work)
static bool test_work_current(struct work *work)
{
bool ret = true;
char *hexstr;
char hexstr[20];
if (work->mandatory)
return ret;
/* 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))
goto out_free;
return ret;
/* 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 */
@ -4049,7 +4047,7 @@ static bool test_work_current(struct work *work) @@ -4049,7 +4047,7 @@ static bool test_work_current(struct work *work)
applog(LOG_DEBUG, "Deleted block %d from database", deleted_block);
set_curblock(hexstr, work->data);
if (unlikely(new_blocks == 1))
goto out_free;
return ret;
work->work_block = ++work_block;
@ -4072,8 +4070,6 @@ static bool test_work_current(struct work *work) @@ -4072,8 +4070,6 @@ static bool test_work_current(struct work *work)
}
}
work->longpoll = false;
out_free:
free(hexstr);
return ret;
}
@ -5467,8 +5463,8 @@ static void *stratum_sthread(void *userdata) @@ -5467,8 +5463,8 @@ static void *stratum_sthread(void *userdata)
quit(1, "Failed to create stratum_q in stratum_sthread");
while (42) {
char noncehex[12], nonce2hex[20];
struct stratum_share *sshare;
char *noncehex, *nonce2hex;
uint32_t *hash32, nonce;
char s[1024], nonce2[8];
struct work *work;
@ -5497,7 +5493,7 @@ static void *stratum_sthread(void *userdata) @@ -5497,7 +5493,7 @@ static void *stratum_sthread(void *userdata)
/* This work item is freed in parse_stratum_response */
sshare->work = work;
nonce = *((uint32_t *)(work->data + 76));
noncehex = bin2hex((const unsigned char *)&nonce, 4);
__bin2hex(noncehex, (const unsigned char *)&nonce, 4);
memset(s, 0, 1024);
mutex_lock(&sshare_lock);
@ -5508,15 +5504,11 @@ static void *stratum_sthread(void *userdata) @@ -5508,15 +5504,11 @@ static void *stratum_sthread(void *userdata)
memset(nonce2, 0, 8);
/* We only use uint32_t sized nonce2 increments internally */
memcpy(nonce2, &work->nonce2, sizeof(uint32_t));
nonce2hex = bin2hex((const unsigned char *)nonce2, work->nonce2_len);
if (unlikely(!nonce2hex))
quit(1, "Failed to bin2hex nonce2 in stratum_thread");
__bin2hex(nonce2hex, (const unsigned char *)nonce2, work->nonce2_len);
snprintf(s, sizeof(s),
"{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
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",
(long unsigned int)htole32(hash32[6]), pool->pool_no);
@ -5974,7 +5966,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work) @@ -5974,7 +5966,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
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;
@ -6532,6 +6524,53 @@ void hash_queued_work(struct thr_info *mythr) @@ -6532,6 +6524,53 @@ void hash_queued_work(struct thr_info *mythr)
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)
{
struct thr_info *mythr = userdata;
@ -7180,6 +7219,8 @@ static void clean_up(void) @@ -7180,6 +7219,8 @@ static void clean_up(void)
clear_adl(nDevs);
#endif
#ifdef USE_USBUTILS
usb_polling = false;
pthread_join(usb_poll_thread, NULL);
libusb_exit(NULL);
#endif
@ -7751,11 +7792,12 @@ static void probe_pools(void) @@ -7751,11 +7792,12 @@ static void probe_pools(void)
#ifdef USE_USBUTILS
static void *libusb_poll_thread(void __maybe_unused *arg)
{
struct timeval tv_end = {0, 200000};
RenameThread("usbpoll");
pthread_detach(pthread_self());
while (usb_polling)
libusb_handle_events(NULL);
libusb_handle_events_timeout_completed(NULL, &tv_end, NULL);
return NULL;
}

16
driver-bitfury.c

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

3
miner.h

@ -952,6 +952,7 @@ extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, @@ -952,6 +952,7 @@ extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
#endif
extern const char *proxytype(proxytypes_t proxytype);
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 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); @@ -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_noffset_nonce(struct thr_info *thr, struct work *work, uint32_t nonce,
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 *__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 *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 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 _wlog(const char *str);
extern void _wlogprint(const char *str);

34
ocl.c

@ -342,6 +342,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize) @@ -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. */
char * devoclver = malloc(1024);
const char * ocl10 = "OpenCL 1.0";
const char * ocl11 = "OpenCL 1.1";
status = clGetDeviceInfo(devices[gpu], CL_DEVICE_VERSION, 1024, (void *)devoclver, NULL);
if (status != CL_SUCCESS) {
@ -349,8 +350,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize) @@ -349,8 +350,12 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
return NULL;
}
find = strstr(devoclver, ocl10);
if (!find)
if (!find) {
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);
if (status != CL_SUCCESS) {
@ -618,19 +623,20 @@ build: @@ -618,19 +623,20 @@ build:
if (clState->hasBitAlign) {
strcat(CompilerOptions, " -D BITALIGN");
applog(LOG_DEBUG, "cl_amd_media_ops found, setting BITALIGN");
if (strstr(name, "Cedar") ||
strstr(name, "Redwood") ||
strstr(name, "Juniper") ||
strstr(name, "Cypress" ) ||
strstr(name, "Hemlock" ) ||
strstr(name, "Caicos" ) ||
strstr(name, "Turks" ) ||
strstr(name, "Barts" ) ||
strstr(name, "Cayman" ) ||
strstr(name, "Antilles" ) ||
strstr(name, "Wrestler" ) ||
strstr(name, "Zacate" ) ||
strstr(name, "WinterPark" ))
if (!clState->hasOpenCL12plus &&
(strstr(name, "Cedar") ||
strstr(name, "Redwood") ||
strstr(name, "Juniper") ||
strstr(name, "Cypress" ) ||
strstr(name, "Hemlock" ) ||
strstr(name, "Caicos" ) ||
strstr(name, "Turks" ) ||
strstr(name, "Barts" ) ||
strstr(name, "Cayman" ) ||
strstr(name, "Antilles" ) ||
strstr(name, "Wrestler" ) ||
strstr(name, "Zacate" ) ||
strstr(name, "WinterPark" )))
patchbfi = true;
} else
applog(LOG_DEBUG, "cl_amd_media_ops not found, will not set BITALIGN");

1
ocl.h

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

34
usbutils.c

@ -2245,7 +2245,6 @@ static int callback_wait(struct usb_transfer *ut, int *transferred, unsigned int @@ -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 */
*transferred = transfer->actual_length;
libusb_free_transfer(transfer);
return ret;
}
@ -2296,6 +2295,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo, @@ -2296,6 +2295,7 @@ usb_bulk_transfer(struct libusb_device_handle *dev_handle, int intinfo,
errn = errno;
if (!err)
err = callback_wait(&ut, transferred, timeout);
libusb_free_transfer(ut.transfer);
STATS_TIMEVAL(&tv_finish);
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 @@ -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)
{
struct usb_transfer ut;
unsigned char buf[70];
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);
mutex_lock(&ut.mutex);
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 @@ -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);
memcpy(buffer, ofbuf, transferred);
return transferred;
err = transferred;
goto out;
}
if ((err) == LIBUSB_TRANSFER_CANCELLED)
err = LIBUSB_ERROR_TIMEOUT;
out:
libusb_free_transfer(ut.transfer);
return err;
}
@ -2812,21 +2812,22 @@ out_: @@ -2812,21 +2812,22 @@ out_:
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 pstate, err;
DEVRLOCK(cgpu, pstate);
DEVWLOCK(cgpu, pstate);
err = __usb_transfer(cgpu, request_type, bRequest, wValue, wIndex, data, siz, timeout, cmd);
if (NOCONTROLDEV(err)) {
cg_ruwlock(&cgpu->usbinfo.devlock);
if (NOCONTROLDEV(err))
release_cgpu(cgpu);
cg_dwlock(&cgpu->usbinfo.devlock);
}
DEVRUNLOCK(cgpu, pstate);
DEVWUNLOCK(cgpu, pstate);
return err;
}
@ -2840,7 +2841,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe @@ -2840,7 +2841,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
unsigned char tbuf[64];
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));
@ -2896,13 +2897,10 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe @@ -2896,13 +2897,10 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
err, libusb_error_name(err));
}
out_noerrmsg:
if (NOCONTROLDEV(err)) {
cg_ruwlock(&cgpu->usbinfo.devlock);
if (NOCONTROLDEV(err))
release_cgpu(cgpu);
cg_dwlock(&cgpu->usbinfo.devlock);
}
DEVRUNLOCK(cgpu, pstate);
DEVWUNLOCK(cgpu, pstate);
return err;
}

14
util.c

@ -584,6 +584,16 @@ char *get_proxy(char *url, struct pool *pool) @@ -584,6 +584,16 @@ char *get_proxy(char *url, struct pool *pool)
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
* array is rounded up to a 4 byte size to appease architectures that need
* aligned array sizes */
@ -591,7 +601,6 @@ char *bin2hex(const unsigned char *p, size_t len) @@ -591,7 +601,6 @@ char *bin2hex(const unsigned char *p, size_t len)
{
ssize_t slen;
char *s;
int i;
slen = len * 2 + 1;
if (slen % 4)
@ -600,8 +609,7 @@ char *bin2hex(const unsigned char *p, size_t len) @@ -600,8 +609,7 @@ char *bin2hex(const unsigned char *p, size_t len)
if (unlikely(!s))
quithere(1, "Failed to calloc");
for (i = 0; i < (int)len; i++)
sprintf(s + (i * 2), "%02x", (unsigned int)p[i]);
__bin2hex(s, p, len);
return s;
}

Loading…
Cancel
Save