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:
commit
9d29e0940a
78
cgminer.c
78
cgminer.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
3
miner.h
3
miner.h
@ -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
12
ocl.c
@ -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
1
ocl.h
@ -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;
|
||||||
|
34
usbutils.c
34
usbutils.c
@ -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
14
util.c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user