Browse Source

Merge with master

nfactor-troky
Con Kolivas 11 years ago
parent
commit
2bbe492f5b
  1. 64
      NEWS
  2. 5
      cgminer.c
  3. 4
      configure.ac
  4. 91
      driver-avalon.c
  5. 11
      driver-avalon.h
  6. 6
      driver-klondike.c
  7. 42
      usbutils.c
  8. 1
      usbutils.h

64
NEWS

@ -1,4 +1,66 @@
Version 3.6.1 - 14th October 2013
- Emulate the libusb_control_transfer sync setup in our async variant.
- usbutils - make all libusb_error_name messages the same
Version 3.6.0 - 14th October 2013
- increasing max miners for avalon driver
- using separate identifier for bitburner fury boards
- changes to bitburner driver for bitburner fury boards
- hexstr is too small in test_work_current
- Windows uses errno for WSAETIMEDOUT
- Convert the usb callback function to using cgsem_t timed waits to avoid race
conditions with conditionals/mutexes.
- Give correct return code in cgsem_mswait
- Check for correct timeout error in cgsem_mswait
- Fix util.h exports for cgsem_mswait
- Implement a generic cgsem_mswait similar to sem_timedwait
- Use the one LIBUSB_ERROR_TIMEOUT for cancelled transactions since this error
is explicitly tested for in various drivers.
- Do not use locking on usb callback function pthread signalling to prevent
deadlock with libusb's own event lock.
- Use a write lock when performing any USB control transfers to prevent
concurrent transfers.
- Free a libusb transfer after we have finished using it to avoid a dereference
in usb_control_transfer
- Do not perform bfi int patching for opencl1.2 or later.
- Although async transfers are meant to use heap memory, we never return before
the transfer function has completed so stack memory will suffice for control
transfers, fixing a memory leak in the process.
- klondike - correct/reverse min/max stats
- api incorrect message name
- klondike - use a link list queue rather than a circular buffer - and add
timing stats
- Use a timeout with usb handle events set to a nominal 200ms and wait for the
polling thread to shut down before deinitialising libusb.
- Use stack memory for hex used in stratum share submissions.
- Use stack memory in test_work_current, avoiding a malloc/free cycle each time.
- Provide a lower level __bin2hex function that does not allocate memory itself.
- Convert the bitfury driver to use the hash_driver_work version of hash_work.
- Add a hash_driver_work function to allow for drivers that wish to do their own
work queueing and management.
- Convert all usb control transfers to asynchronous communication with our own
timeout management as well.
- Klondike - increase circular read buffer size
- Klondike - extra zero value and range checking in temp conversion
- klondike - display MHz also
- Make pthread conditional timeouts handle all bulk usb transfer timeouts
performing libusb_cancel_transfer, disabling timeouts within libusb itself.
- Avoid calling get_statline_before on exit to avoid trying to use it on drivers
in an indeterminate state.
- Avoid calling get_statline on exit.
- Add a small amount to the usb timeout before cancelling to allow for a regular
usb polling interval to pass.
- Do not attempt to clear a usb halt before sending the cancel message since all
transfers should normally be cancelled before attempting to clear a halt
condition, and only change the return message to a timeout if it's consistent
with a cancellation.
- Retry up to USB_RETRY_MAX times to clear a halt condition before failing.
- Show the error number as well as the description in erroring bulk transfers.
- Drop logging level for failed to connect to stratum to verbose mode only since
we hit it regularly.
- We are always dependent on libusb handling events so use the blocking - We are always dependent on libusb handling events so use the blocking
libusb_handle_events in the polling thread and use a bool to know if we should libusb_handle_events in the polling thread and use a bool to know if we should
continue polling. continue polling.

5
cgminer.c

@ -1245,7 +1245,10 @@ static struct opt_table opt_config_table[] = {
"Set avalon target temperature"), "Set avalon target temperature"),
OPT_WITH_ARG("--bitburner-voltage", OPT_WITH_ARG("--bitburner-voltage",
opt_set_intval, NULL, &opt_bitburner_core_voltage, opt_set_intval, NULL, &opt_bitburner_core_voltage,
"Set BitBurner core voltage, in millivolts"), "Set BitBurner (Avalon) core voltage, in millivolts"),
OPT_WITH_ARG("--bitburner-fury-voltage",
opt_set_intval, NULL, &opt_bitburner_fury_core_voltage,
"Set BitBurner Fury core voltage, in millivolts"),
#endif #endif
#ifdef USE_KLONDIKE #ifdef USE_KLONDIKE
OPT_WITH_ARG("--klondike-options", OPT_WITH_ARG("--klondike-options",

4
configure.ac

@ -1,8 +1,8 @@
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_maj], [3]) m4_define([v_maj], [3])
m4_define([v_min], [5]) m4_define([v_min], [6])
m4_define([v_mic], [0]) m4_define([v_mic], [1])
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--## ##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
m4_define([v_ver], [v_maj.v_min.v_mic]) m4_define([v_ver], [v_maj.v_min.v_mic])
m4_define([lt_rev], m4_eval(v_maj + v_min)) m4_define([lt_rev], m4_eval(v_maj + v_min))

91
driver-avalon.c

@ -49,6 +49,7 @@ int opt_avalon_fan_max = AVALON_DEFAULT_FAN_MAX_PWM;
int opt_avalon_freq_min = AVALON_MIN_FREQUENCY; int opt_avalon_freq_min = AVALON_MIN_FREQUENCY;
int opt_avalon_freq_max = AVALON_MAX_FREQUENCY; int opt_avalon_freq_max = AVALON_MAX_FREQUENCY;
int opt_bitburner_core_voltage = BITBURNER_DEFAULT_CORE_VOLTAGE; int opt_bitburner_core_voltage = BITBURNER_DEFAULT_CORE_VOLTAGE;
int opt_bitburner_fury_core_voltage = BITBURNER_FURY_DEFAULT_CORE_VOLTAGE;
bool opt_avalon_auto; bool opt_avalon_auto;
static int option_offset = -1; static int option_offset = -1;
@ -209,6 +210,55 @@ static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *aval
return ret; return ret;
} }
static int bitburner_send_task(const struct avalon_task *at, struct cgpu_info *avalon)
{
uint8_t buf[AVALON_WRITE_SIZE + 4 * AVALON_DEFAULT_ASIC_NUM];
int ret, ep = C_AVALON_TASK;
cgtimer_t ts_start;
size_t nr_len;
if (at->nonce_elf)
nr_len = AVALON_WRITE_SIZE + 4 * at->asic_num;
else
nr_len = AVALON_WRITE_SIZE;
memset(buf, 0, nr_len);
memcpy(buf, at, AVALON_WRITE_SIZE);
#if defined(__BIG_ENDIAN__) || defined(MIPSEB)
uint8_t tt = 0;
tt = (buf[0] & 0x0f) << 4;
tt |= ((buf[0] & 0x10) ? (1 << 3) : 0);
tt |= ((buf[0] & 0x20) ? (1 << 2) : 0);
tt |= ((buf[0] & 0x40) ? (1 << 1) : 0);
tt |= ((buf[0] & 0x80) ? (1 << 0) : 0);
buf[0] = tt;
tt = (buf[4] & 0x0f) << 4;
tt |= ((buf[4] & 0x10) ? (1 << 3) : 0);
tt |= ((buf[4] & 0x20) ? (1 << 2) : 0);
tt |= ((buf[4] & 0x40) ? (1 << 1) : 0);
tt |= ((buf[4] & 0x80) ? (1 << 0) : 0);
buf[4] = tt;
#endif
if (at->reset) {
ep = C_AVALON_RESET;
nr_len = 1;
}
if (opt_debug) {
applog(LOG_DEBUG, "Avalon: Sent(%u):", (unsigned int)nr_len);
hexdump(buf, nr_len);
}
cgsleep_prepare_r(&ts_start);
ret = avalon_write(avalon, (char *)buf, nr_len, ep);
cgsleep_us_r(&ts_start, 3000); // 3 ms = 333 tasks per second, or 1.4 TH/s
return ret;
}
static bool avalon_decode_nonce(struct thr_info *thr, struct cgpu_info *avalon, static bool avalon_decode_nonce(struct thr_info *thr, struct cgpu_info *avalon,
struct avalon_info *info, struct avalon_result *ar, struct avalon_info *info, struct avalon_result *ar,
struct work *work) struct work *work)
@ -414,12 +464,12 @@ static bool get_options(int this_option_offset, int *baud, int *miner_count,
if (*colon) { if (*colon) {
tmp = atoi(colon); tmp = atoi(colon);
if (tmp > 0 && tmp <= AVALON_DEFAULT_MINER_NUM) { if (tmp > 0 && tmp <= AVALON_MAX_MINER_NUM) {
*miner_count = tmp; *miner_count = tmp;
} else { } else {
quit(1, "Invalid avalon-options for " quit(1, "Invalid avalon-options for "
"miner_count (%s) must be 1 ~ %d", "miner_count (%s) must be 1 ~ %d",
colon, AVALON_DEFAULT_MINER_NUM); colon, AVALON_MAX_MINER_NUM);
} }
} }
@ -620,12 +670,20 @@ static void avalon_initialise(struct cgpu_info *avalon)
avalon->drv->name, avalon->device_id, err); avalon->drv->name, avalon->device_id, err);
} }
static bool is_bitburner(struct cgpu_info *avalon)
{
enum sub_ident ident;
ident = usb_ident(avalon);
return ident == IDENT_BTB || ident == IDENT_BBF;
}
static bool bitburner_set_core_voltage(struct cgpu_info *avalon, int core_voltage) static bool bitburner_set_core_voltage(struct cgpu_info *avalon, int core_voltage)
{ {
uint8_t buf[2]; uint8_t buf[2];
int err; int err;
if (usb_ident(avalon) == IDENT_BTB) { if (is_bitburner(avalon)) {
buf[0] = (uint8_t)core_voltage; buf[0] = (uint8_t)core_voltage;
buf[1] = (uint8_t)(core_voltage >> 8); buf[1] = (uint8_t)(core_voltage >> 8);
err = usb_transfer_data(avalon, FTDI_TYPE_OUT, BITBURNER_REQUEST, err = usb_transfer_data(avalon, FTDI_TYPE_OUT, BITBURNER_REQUEST,
@ -651,7 +709,7 @@ static int bitburner_get_core_voltage(struct cgpu_info *avalon)
int err; int err;
int amount; int amount;
if (usb_ident(avalon) == IDENT_BTB) { if (is_bitburner(avalon)) {
err = usb_transfer_read(avalon, FTDI_TYPE_IN, BITBURNER_REQUEST, err = usb_transfer_read(avalon, FTDI_TYPE_IN, BITBURNER_REQUEST,
BITBURNER_VALUE, BITBURNER_INDEX_GET_VOLTAGE, BITBURNER_VALUE, BITBURNER_INDEX_GET_VOLTAGE,
(char *)buf, sizeof(buf), &amount, (char *)buf, sizeof(buf), &amount,
@ -780,7 +838,18 @@ static bool avalon_detect_one(libusb_device *dev, struct usb_find_devices *found
BITBURNER_MAX_COREMV); BITBURNER_MAX_COREMV);
} else } else
bitburner_set_core_voltage(avalon, opt_bitburner_core_voltage); bitburner_set_core_voltage(avalon, opt_bitburner_core_voltage);
} else if (usb_ident(avalon) == IDENT_BBF) {
if (opt_bitburner_fury_core_voltage < BITBURNER_FURY_MIN_COREMV ||
opt_bitburner_fury_core_voltage > BITBURNER_FURY_MAX_COREMV) {
quit(1, "Invalid bitburner-fury-voltage %d must be %dmv - %dmv",
opt_bitburner_fury_core_voltage,
BITBURNER_FURY_MIN_COREMV,
BITBURNER_FURY_MAX_COREMV);
} else
bitburner_set_core_voltage(avalon, opt_bitburner_fury_core_voltage);
}
if (is_bitburner(avalon)) {
bitburner_get_version(avalon); bitburner_get_version(avalon);
} }
@ -1181,7 +1250,7 @@ static void *bitburner_send_tasks(void *userdata)
avalon_reset_auto(info); avalon_reset_auto(info);
} }
ret = avalon_send_task(&at, avalon); ret = bitburner_send_task(&at, avalon);
if (unlikely(ret == AVA_SEND_ERROR)) { if (unlikely(ret == AVA_SEND_ERROR)) {
applog(LOG_ERR, "%s%i: Comms error(buffer)", applog(LOG_ERR, "%s%i: Comms error(buffer)",
@ -1211,7 +1280,7 @@ static bool avalon_prepare(struct thr_info *thr)
int array_size = AVALON_ARRAY_SIZE; int array_size = AVALON_ARRAY_SIZE;
void *(*write_thread_fn)(void *) = avalon_send_tasks; void *(*write_thread_fn)(void *) = avalon_send_tasks;
if (usb_ident(avalon) == IDENT_BTB) { if (is_bitburner(avalon)) {
array_size = BITBURNER_ARRAY_SIZE; array_size = BITBURNER_ARRAY_SIZE;
write_thread_fn = bitburner_send_tasks; write_thread_fn = bitburner_send_tasks;
} }
@ -1356,7 +1425,7 @@ static void avalon_update_temps(struct cgpu_info *avalon, struct avalon_info *in
info->temp_sum += avalon->temp; info->temp_sum += avalon->temp;
applog(LOG_DEBUG, "Avalon: temp_index: %d, temp_count: %d, temp_old: %d", applog(LOG_DEBUG, "Avalon: temp_index: %d, temp_count: %d, temp_old: %d",
info->temp_history_index, info->temp_history_count, info->temp_old); info->temp_history_index, info->temp_history_count, info->temp_old);
if (usb_ident(avalon) == IDENT_BTB) { if (is_bitburner(avalon)) {
info->core_voltage = bitburner_get_core_voltage(avalon); info->core_voltage = bitburner_get_core_voltage(avalon);
} }
if (info->temp_history_index == info->temp_history_count) { if (info->temp_history_index == info->temp_history_count) {
@ -1378,7 +1447,7 @@ static void get_avalon_statline_before(char *buf, size_t bufsiz, struct cgpu_inf
struct avalon_info *info = avalon->device_data; struct avalon_info *info = avalon->device_data;
int lowfan = 10000; int lowfan = 10000;
if (usb_ident(avalon) == IDENT_BTB) { if (is_bitburner(avalon)) {
int temp = info->temp0; int temp = info->temp0;
if (info->temp2 > temp) if (info->temp2 > temp)
temp = info->temp2; temp = info->temp2;
@ -1464,7 +1533,7 @@ static int64_t avalon_scanhash(struct thr_info *thr)
/* Check for nothing but consecutive bad results or consistently less /* Check for nothing but consecutive bad results or consistently less
* results than we should be getting and reset the FPGA if necessary */ * results than we should be getting and reset the FPGA if necessary */
if (usb_ident(avalon) != IDENT_BTB) { if (!is_bitburner(avalon)) {
if (avalon->results < -miner_count && !info->reset) { if (avalon->results < -miner_count && !info->reset) {
applog(LOG_ERR, "%s%d: Result return rate low, resetting!", applog(LOG_ERR, "%s%d: Result return rate low, resetting!",
avalon->drv->name, avalon->device_id); avalon->drv->name, avalon->device_id);
@ -1525,7 +1594,7 @@ static struct api_data *avalon_api_stats(struct cgpu_info *cgpu)
sprintf(mcw, "match_work_count%d", i + 1); sprintf(mcw, "match_work_count%d", i + 1);
root = api_add_int(root, mcw, &(info->matching_work[i]), false); root = api_add_int(root, mcw, &(info->matching_work[i]), false);
} }
if (usb_ident(cgpu) == IDENT_BTB) { if (is_bitburner(cgpu)) {
root = api_add_int(root, "core_voltage", &(info->core_voltage), false); root = api_add_int(root, "core_voltage", &(info->core_voltage), false);
snprintf(buf, sizeof(buf), "%"PRIu8".%"PRIu8".%"PRIu8, snprintf(buf, sizeof(buf), "%"PRIu8".%"PRIu8".%"PRIu8,
info->version1, info->version2, info->version3); info->version1, info->version2, info->version3);
@ -1553,7 +1622,7 @@ static char *avalon_set_device(struct cgpu_info *avalon, char *option, char *set
} }
if (strcasecmp(option, "millivolts") == 0 || strcasecmp(option, "mv") == 0) { if (strcasecmp(option, "millivolts") == 0 || strcasecmp(option, "mv") == 0) {
if (usb_ident(avalon) != IDENT_BTB) { if (!is_bitburner(avalon)) {
sprintf(replybuf, "%s cannot set millivolts", avalon->drv->name); sprintf(replybuf, "%s cannot set millivolts", avalon->drv->name);
return replybuf; return replybuf;
} }

11
driver-avalon.h

@ -33,11 +33,18 @@
#define AVALON_TEMP_HYSTERESIS 3 #define AVALON_TEMP_HYSTERESIS 3
#define AVALON_TEMP_OVERHEAT 60 #define AVALON_TEMP_OVERHEAT 60
/* Avalon-based BitBurner. */
#define BITBURNER_DEFAULT_CORE_VOLTAGE 1200 /* in millivolts */ #define BITBURNER_DEFAULT_CORE_VOLTAGE 1200 /* in millivolts */
#define BITBURNER_MIN_COREMV 1000 #define BITBURNER_MIN_COREMV 1000
/* change here if you want to risk killing it :) */ /* change here if you want to risk killing it :) */
#define BITBURNER_MAX_COREMV 1400 #define BITBURNER_MAX_COREMV 1400
/* BitFury-based BitBurner. */
#define BITBURNER_FURY_DEFAULT_CORE_VOLTAGE 900 /* in millivolts */
#define BITBURNER_FURY_MIN_COREMV 700
/* change here if you want to risk killing it :) */
#define BITBURNER_FURY_MAX_COREMV 1100
#define AVALON_DEFAULT_TIMEOUT 0x2D #define AVALON_DEFAULT_TIMEOUT 0x2D
#define AVALON_MIN_FREQUENCY 256 #define AVALON_MIN_FREQUENCY 256
@ -45,6 +52,7 @@
#define AVALON_TIMEOUT_FACTOR 12690 #define AVALON_TIMEOUT_FACTOR 12690
#define AVALON_DEFAULT_FREQUENCY 282 #define AVALON_DEFAULT_FREQUENCY 282
#define AVALON_DEFAULT_MINER_NUM 0x20 #define AVALON_DEFAULT_MINER_NUM 0x20
#define AVALON_MAX_MINER_NUM 0x100
#define AVALON_DEFAULT_ASIC_NUM 0xA #define AVALON_DEFAULT_ASIC_NUM 0xA
#define AVALON_AUTO_CYCLE 1024 #define AVALON_AUTO_CYCLE 1024
@ -122,7 +130,7 @@ struct avalon_info {
int core_voltage; int core_voltage;
int no_matching_work; int no_matching_work;
int matching_work[AVALON_DEFAULT_MINER_NUM]; int matching_work[AVALON_MAX_MINER_NUM];
int frequency; int frequency;
uint32_t ctlr_ver; uint32_t ctlr_ver;
@ -179,6 +187,7 @@ extern int opt_avalon_freq_min;
extern int opt_avalon_freq_max; extern int opt_avalon_freq_max;
extern bool opt_avalon_auto; extern bool opt_avalon_auto;
extern int opt_bitburner_core_voltage; extern int opt_bitburner_core_voltage;
extern int opt_bitburner_fury_core_voltage;
extern char *set_avalon_fan(char *arg); extern char *set_avalon_fan(char *arg);
extern char *set_avalon_freq(char *arg); extern char *set_avalon_freq(char *arg);

6
driver-klondike.c

@ -696,8 +696,9 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, KLIST *kitem)
klninfo->delay_count++; klninfo->delay_count++;
klninfo->delay_total += us_diff; klninfo->delay_total += us_diff;
if (klninfo->nonce_count > 0) {
us_diff = us_tdiff(&(kitem->tv_when), &(klninfo->tv_last_nonce_received)); us_diff = us_tdiff(&(kitem->tv_when), &(klninfo->tv_last_nonce_received));
if (klninfo->nonce_count == 0) { if (klninfo->nonce_count == 1) {
klninfo->nonce_min = us_diff; klninfo->nonce_min = us_diff;
klninfo->nonce_max = us_diff; klninfo->nonce_max = us_diff;
} else { } else {
@ -706,8 +707,9 @@ static void klondike_check_nonce(struct cgpu_info *klncgpu, KLIST *kitem)
if (klninfo->nonce_max < us_diff) if (klninfo->nonce_max < us_diff)
klninfo->nonce_max = us_diff; klninfo->nonce_max = us_diff;
} }
klninfo->nonce_count++;
klninfo->nonce_total += us_diff; klninfo->nonce_total += us_diff;
}
klninfo->nonce_count++;
memcpy(&(klninfo->tv_last_nonce_received), &(kitem->tv_when), memcpy(&(klninfo->tv_last_nonce_received), &(kitem->tv_when),
sizeof(klninfo->tv_last_nonce_received)); sizeof(klninfo->tv_last_nonce_received));

42
usbutils.c

@ -309,6 +309,18 @@ static struct usb_find_devices find_dev[] = {
.timeout = AVALON_TIMEOUT_MS, .timeout = AVALON_TIMEOUT_MS,
.latency = 10, .latency = 10,
INTINFO(ava_ints) }, INTINFO(ava_ints) },
{
.drv = DRIVER_avalon,
.name = "BBF",
.ident = IDENT_BBF,
.idVendor = IDVENDOR_FTDI,
.idProduct = 0x6001,
.iManufacturer = "Burnin Electronics",
.iProduct = "BitBurner Fury",
.config = 1,
.timeout = AVALON_TIMEOUT_MS,
.latency = 10,
INTINFO(ava_ints) },
{ {
.drv = DRIVER_avalon, .drv = DRIVER_avalon,
.name = "AVA", .name = "AVA",
@ -798,11 +810,11 @@ static void usb_full(ssize_t *count, libusb_device *dev, char **buf, size_t *off
err = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, man, STRBUFLEN); err = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, man, STRBUFLEN);
if (err < 0) if (err < 0)
snprintf((char *)man, sizeof(man), "** err(%d)%s", err, libusb_error_name(err)); snprintf((char *)man, sizeof(man), "** err:(%d) %s", err, libusb_error_name(err));
err = libusb_get_string_descriptor_ascii(handle, desc.iProduct, prod, STRBUFLEN); err = libusb_get_string_descriptor_ascii(handle, desc.iProduct, prod, STRBUFLEN);
if (err < 0) if (err < 0)
snprintf((char *)prod, sizeof(prod), "** err(%d)%s", err, libusb_error_name(err)); snprintf((char *)prod, sizeof(prod), "** err:(%d) %s", err, libusb_error_name(err));
if (level == 0) { if (level == 0) {
libusb_close(handle); libusb_close(handle);
@ -878,7 +890,7 @@ static void usb_full(ssize_t *count, libusb_device *dev, char **buf, size_t *off
err = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, ser, STRBUFLEN); err = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, ser, STRBUFLEN);
if (err < 0) if (err < 0)
snprintf((char *)ser, sizeof(ser), "** err(%d)%s", err, libusb_error_name(err)); snprintf((char *)ser, sizeof(ser), "** err:(%d) %s", err, libusb_error_name(err));
snprintf(tmp, sizeof(tmp), EOL " dev %d: More Info:" EOL "\tManufacturer: '%s'" EOL snprintf(tmp, sizeof(tmp), EOL " dev %d: More Info:" EOL "\tManufacturer: '%s'" EOL
"\tProduct: '%s'" EOL "\tSerial '%s'", "\tProduct: '%s'" EOL "\tSerial '%s'",
@ -898,7 +910,7 @@ void usb_all(int level)
count = libusb_get_device_list(NULL, &list); count = libusb_get_device_list(NULL, &list);
if (count < 0) { if (count < 0) {
applog(LOG_ERR, "USB all: failed, err %d%s", (int)count, libusb_error_name((int)count)); applog(LOG_ERR, "USB all: failed, err:(%d) %s", (int)count, libusb_error_name((int)count));
return; return;
} }
@ -2577,8 +2589,8 @@ int _usb_read(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_t
out_unlock: out_unlock:
if (err && err != LIBUSB_ERROR_TIMEOUT) { if (err && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_WARNING, "%s %i usb read error: %s", cgpu->drv->name, cgpu->device_id, applog(LOG_WARNING, "%s %i usb read err:(%d) %s", cgpu->drv->name, cgpu->device_id,
libusb_error_name(err)); err, libusb_error_name(err));
if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX) if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX)
err = LIBUSB_ERROR_OTHER; err = LIBUSB_ERROR_OTHER;
} }
@ -2677,8 +2689,8 @@ int _usb_write(struct cgpu_info *cgpu, int intinfo, int epinfo, char *buf, size_
*processed = tot; *processed = tot;
if (err) { if (err) {
applog(LOG_WARNING, "%s %i usb write error: %s", cgpu->drv->name, cgpu->device_id, applog(LOG_WARNING, "%s %i usb write err:(%d) %s", cgpu->drv->name, cgpu->device_id,
libusb_error_name(err)); err, libusb_error_name(err));
if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX) if (cgpu->usbinfo.continuous_ioerr_count > USB_RETRY_MAX)
err = LIBUSB_ERROR_OTHER; err = LIBUSB_ERROR_OTHER;
} }
@ -2707,15 +2719,17 @@ static int usb_control_transfer(libusb_device_handle *dev_handle, uint8_t bmRequ
init_usb_transfer(&ut); init_usb_transfer(&ut);
libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue, libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue,
wIndex, wLength); wIndex, wLength);
if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
memcpy(buf + LIBUSB_CONTROL_SETUP_SIZE, buffer, wLength);
libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback, libusb_fill_control_transfer(ut.transfer, dev_handle, buf, transfer_callback,
&ut, 0); &ut, 0);
err = libusb_submit_transfer(ut.transfer); err = libusb_submit_transfer(ut.transfer);
if (!err) if (!err)
err = callback_wait(&ut, &transferred, timeout); err = callback_wait(&ut, &transferred, timeout);
if (!err && transferred) { if (err == LIBUSB_TRANSFER_COMPLETED && transferred) {
unsigned char *ofbuf = libusb_control_transfer_get_data(ut.transfer); if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
memcpy(buffer, libusb_control_transfer_get_data(ut.transfer),
memcpy(buffer, ofbuf, transferred); transferred);
err = transferred; err = transferred;
goto out; goto out;
} }
@ -2793,7 +2807,7 @@ int __usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bReques
IOERR_CHECK(cgpu, err); IOERR_CHECK(cgpu, err);
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) { if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_WARNING, "%s %i usb transfer error(%d): %s", cgpu->drv->name, cgpu->device_id, applog(LOG_WARNING, "%s %i usb transfer err:(%d) %s", cgpu->drv->name, cgpu->device_id,
err, libusb_error_name(err)); err, libusb_error_name(err));
} }
out_: out_:
@ -2881,7 +2895,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
err = 0; err = 0;
} }
if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) { if (err < 0 && err != LIBUSB_ERROR_TIMEOUT) {
applog(LOG_WARNING, "%s %i usb transfer read error(%d): %s", cgpu->drv->name, cgpu->device_id, applog(LOG_WARNING, "%s %i usb transfer read err:(%d) %s", cgpu->drv->name, cgpu->device_id,
err, libusb_error_name(err)); err, libusb_error_name(err));
} }
out_noerrmsg: out_noerrmsg:

1
usbutils.h

@ -148,6 +148,7 @@ enum sub_ident {
IDENT_MMQ, IDENT_MMQ,
IDENT_AVA, IDENT_AVA,
IDENT_BTB, IDENT_BTB,
IDENT_BBF,
IDENT_KLN, IDENT_KLN,
IDENT_ICA, IDENT_ICA,
IDENT_AMU, IDENT_AMU,

Loading…
Cancel
Save