|
|
@ -336,8 +336,28 @@ struct usb_in_use_list { |
|
|
|
// List of in use devices
|
|
|
|
// List of in use devices
|
|
|
|
static struct usb_in_use_list *in_use_head = NULL; |
|
|
|
static struct usb_in_use_list *in_use_head = NULL; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Set this to 0 to remove stats processing
|
|
|
|
|
|
|
|
#define DO_USB_STATS 1 |
|
|
|
|
|
|
|
|
|
|
|
static bool stats_initialised = false; |
|
|
|
static bool stats_initialised = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if DO_USB_STATS |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// NONE must be 0 - calloced
|
|
|
|
|
|
|
|
#define MODE_NONE 0 |
|
|
|
|
|
|
|
#define MODE_CTRL_READ (1 << 0) |
|
|
|
|
|
|
|
#define MODE_CTRL_WRITE (1 << 1) |
|
|
|
|
|
|
|
#define MODE_BULK_READ (1 << 2) |
|
|
|
|
|
|
|
#define MODE_BULK_WRITE (1 << 3) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MODE_SEP_STR "+" |
|
|
|
|
|
|
|
#define MODE_NONE_STR "X" |
|
|
|
|
|
|
|
#define MODE_CTRL_READ_STR "cr" |
|
|
|
|
|
|
|
#define MODE_CTRL_WRITE_STR "cw" |
|
|
|
|
|
|
|
#define MODE_BULK_READ_STR "br" |
|
|
|
|
|
|
|
#define MODE_BULK_WRITE_STR "bw" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// One for each CMD, TIMEOUT, ERROR
|
|
|
|
struct cg_usb_stats_item { |
|
|
|
struct cg_usb_stats_item { |
|
|
|
uint64_t count; |
|
|
|
uint64_t count; |
|
|
|
double total_delay; |
|
|
|
double total_delay; |
|
|
@ -351,11 +371,14 @@ struct cg_usb_stats_item { |
|
|
|
#define CMD_TIMEOUT 1 |
|
|
|
#define CMD_TIMEOUT 1 |
|
|
|
#define CMD_ERROR 2 |
|
|
|
#define CMD_ERROR 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// One for each C_CMD
|
|
|
|
struct cg_usb_stats_details { |
|
|
|
struct cg_usb_stats_details { |
|
|
|
int seq; |
|
|
|
int seq; |
|
|
|
|
|
|
|
uint32_t modes; |
|
|
|
struct cg_usb_stats_item item[CMD_ERROR+1]; |
|
|
|
struct cg_usb_stats_item item[CMD_ERROR+1]; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// One for each device
|
|
|
|
struct cg_usb_stats { |
|
|
|
struct cg_usb_stats { |
|
|
|
char *name; |
|
|
|
char *name; |
|
|
|
int device_id; |
|
|
|
int device_id; |
|
|
@ -368,6 +391,17 @@ struct cg_usb_stats { |
|
|
|
static struct cg_usb_stats *usb_stats = NULL; |
|
|
|
static struct cg_usb_stats *usb_stats = NULL; |
|
|
|
static int next_stat = 0; |
|
|
|
static int next_stat = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define USB_STATS(sgpu, sta, fin, err, mode, cmd, seq) \ |
|
|
|
|
|
|
|
stats(cgpu, sta, fin, err, mode, cmd, seq) |
|
|
|
|
|
|
|
#define STATS_TIMEVAL(tv) cgtime(tv) |
|
|
|
|
|
|
|
#define USB_REJECT(sgpu, mode) rejected_inc(sgpu, mode) |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
#define USB_STATS(sgpu, sta, fin, err, mode, cmd, seq) |
|
|
|
|
|
|
|
#define STATS_TIMEVAL(tv) |
|
|
|
|
|
|
|
#define USB_REJECT(sgpu, mode) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // DO_USB_STATS
|
|
|
|
|
|
|
|
|
|
|
|
static const char **usb_commands; |
|
|
|
static const char **usb_commands; |
|
|
|
|
|
|
|
|
|
|
|
static const char *C_REJECTED_S = "RejectedNoDevice"; |
|
|
|
static const char *C_REJECTED_S = "RejectedNoDevice"; |
|
|
@ -1783,15 +1817,45 @@ void usb_detect(struct device_drv *drv, bool (*device_detect)(struct libusb_devi |
|
|
|
libusb_free_device_list(list, 1); |
|
|
|
libusb_free_device_list(list, 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Set this to 0 to remove stats processing
|
|
|
|
|
|
|
|
#define DO_USB_STATS 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if DO_USB_STATS |
|
|
|
#if DO_USB_STATS |
|
|
|
#define USB_STATS(sgpu, sta, fin, err, cmd, seq) stats(cgpu, sta, fin, err, cmd, seq) |
|
|
|
static void modes_str(char *buf, uint32_t modes) |
|
|
|
#define STATS_TIMEVAL(tv) cgtime(tv) |
|
|
|
{ |
|
|
|
#else |
|
|
|
bool first; |
|
|
|
#define USB_STATS(sgpu, sta, fin, err, cmd, seq) |
|
|
|
|
|
|
|
#define STATS_TIMEVAL(tv) |
|
|
|
*buf = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (modes == MODE_NONE) |
|
|
|
|
|
|
|
strcpy(buf, MODE_NONE_STR); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
first = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (modes & MODE_CTRL_READ) { |
|
|
|
|
|
|
|
strcpy(buf, MODE_CTRL_READ_STR); |
|
|
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (modes & MODE_CTRL_WRITE) { |
|
|
|
|
|
|
|
if (!first) |
|
|
|
|
|
|
|
strcat(buf, MODE_SEP_STR); |
|
|
|
|
|
|
|
strcat(buf, MODE_CTRL_WRITE_STR); |
|
|
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (modes & MODE_BULK_READ) { |
|
|
|
|
|
|
|
if (!first) |
|
|
|
|
|
|
|
strcat(buf, MODE_SEP_STR); |
|
|
|
|
|
|
|
strcat(buf, MODE_BULK_READ_STR); |
|
|
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (modes & MODE_BULK_WRITE) { |
|
|
|
|
|
|
|
if (!first) |
|
|
|
|
|
|
|
strcat(buf, MODE_SEP_STR); |
|
|
|
|
|
|
|
strcat(buf, MODE_BULK_WRITE_STR); |
|
|
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// The stat data can be spurious due to not locking it before copying it -
|
|
|
|
// The stat data can be spurious due to not locking it before copying it -
|
|
|
@ -1806,6 +1870,7 @@ struct api_data *api_usb_stats(__maybe_unused int *count) |
|
|
|
struct api_data *root = NULL; |
|
|
|
struct api_data *root = NULL; |
|
|
|
int device; |
|
|
|
int device; |
|
|
|
int cmdseq; |
|
|
|
int cmdseq; |
|
|
|
|
|
|
|
char modes_s[32]; |
|
|
|
|
|
|
|
|
|
|
|
if (next_stat == 0) |
|
|
|
if (next_stat == 0) |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
@ -1829,6 +1894,8 @@ struct api_data *api_usb_stats(__maybe_unused int *count) |
|
|
|
root = api_add_int(root, "ID", &(sta->device_id), false); |
|
|
|
root = api_add_int(root, "ID", &(sta->device_id), false); |
|
|
|
root = api_add_const(root, "Stat", usb_commands[cmdseq/2], false); |
|
|
|
root = api_add_const(root, "Stat", usb_commands[cmdseq/2], false); |
|
|
|
root = api_add_int(root, "Seq", &(details->seq), true); |
|
|
|
root = api_add_int(root, "Seq", &(details->seq), true); |
|
|
|
|
|
|
|
modes_str(modes_s, details->modes); |
|
|
|
|
|
|
|
root = api_add_string(root, "Modes", modes_s, true); |
|
|
|
root = api_add_uint64(root, "Count", |
|
|
|
root = api_add_uint64(root, "Count", |
|
|
|
&(details->item[CMD_CMD].count), true); |
|
|
|
&(details->item[CMD_CMD].count), true); |
|
|
|
root = api_add_double(root, "Total Delay", |
|
|
|
root = api_add_double(root, "Total Delay", |
|
|
@ -1882,10 +1949,15 @@ static void newstats(struct cgpu_info *cgpu) |
|
|
|
mutex_unlock(&cgusb_lock); |
|
|
|
mutex_unlock(&cgusb_lock); |
|
|
|
|
|
|
|
|
|
|
|
usb_stats = realloc(usb_stats, sizeof(*usb_stats) * next_stat); |
|
|
|
usb_stats = realloc(usb_stats, sizeof(*usb_stats) * next_stat); |
|
|
|
|
|
|
|
if (!usb_stats) |
|
|
|
|
|
|
|
quit(1, "USB failed to realloc usb_stats %d", next_stat); |
|
|
|
|
|
|
|
|
|
|
|
usb_stats[next_stat-1].name = cgpu->drv->name; |
|
|
|
usb_stats[next_stat-1].name = cgpu->drv->name; |
|
|
|
usb_stats[next_stat-1].device_id = -1; |
|
|
|
usb_stats[next_stat-1].device_id = -1; |
|
|
|
usb_stats[next_stat-1].details = calloc(1, sizeof(struct cg_usb_stats_details) * C_MAX * 2); |
|
|
|
usb_stats[next_stat-1].details = calloc(1, sizeof(struct cg_usb_stats_details) * C_MAX * 2); |
|
|
|
|
|
|
|
if (!usb_stats[next_stat-1].details) |
|
|
|
|
|
|
|
quit(1, "USB failed to calloc details for %d", next_stat); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 1; i < C_MAX * 2; i += 2) |
|
|
|
for (i = 1; i < C_MAX * 2; i += 2) |
|
|
|
usb_stats[next_stat-1].details[i].seq = 1; |
|
|
|
usb_stats[next_stat-1].details[i].seq = 1; |
|
|
|
} |
|
|
|
} |
|
|
@ -1903,7 +1975,7 @@ void update_usb_stats(__maybe_unused struct cgpu_info *cgpu) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if DO_USB_STATS |
|
|
|
#if DO_USB_STATS |
|
|
|
static void stats(struct cgpu_info *cgpu, struct timeval *tv_start, struct timeval *tv_finish, int err, enum usb_cmds cmd, int seq) |
|
|
|
static void stats(struct cgpu_info *cgpu, struct timeval *tv_start, struct timeval *tv_finish, int err, int mode, enum usb_cmds cmd, int seq) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_stats_details *details; |
|
|
|
struct cg_usb_stats_details *details; |
|
|
|
double diff; |
|
|
|
double diff; |
|
|
@ -1913,6 +1985,7 @@ static void stats(struct cgpu_info *cgpu, struct timeval *tv_start, struct timev |
|
|
|
newstats(cgpu); |
|
|
|
newstats(cgpu); |
|
|
|
|
|
|
|
|
|
|
|
details = &(usb_stats[cgpu->usbinfo.usbstat - 1].details[cmd * 2 + seq]); |
|
|
|
details = &(usb_stats[cgpu->usbinfo.usbstat - 1].details[cmd * 2 + seq]); |
|
|
|
|
|
|
|
details->modes |= mode; |
|
|
|
|
|
|
|
|
|
|
|
diff = tdiff(tv_finish, tv_start); |
|
|
|
diff = tdiff(tv_finish, tv_start); |
|
|
|
|
|
|
|
|
|
|
@ -1942,7 +2015,7 @@ static void stats(struct cgpu_info *cgpu, struct timeval *tv_start, struct timev |
|
|
|
details->item[item].count++; |
|
|
|
details->item[item].count++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void rejected_inc(struct cgpu_info *cgpu) |
|
|
|
static void rejected_inc(struct cgpu_info *cgpu, uint32_t mode) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_stats_details *details; |
|
|
|
struct cg_usb_stats_details *details; |
|
|
|
int item = CMD_ERROR; |
|
|
|
int item = CMD_ERROR; |
|
|
@ -1951,14 +2024,14 @@ static void rejected_inc(struct cgpu_info *cgpu) |
|
|
|
newstats(cgpu); |
|
|
|
newstats(cgpu); |
|
|
|
|
|
|
|
|
|
|
|
details = &(usb_stats[cgpu->usbinfo.usbstat - 1].details[C_REJECTED * 2 + 0]); |
|
|
|
details = &(usb_stats[cgpu->usbinfo.usbstat - 1].details[C_REJECTED * 2 + 0]); |
|
|
|
|
|
|
|
details->modes |= mode; |
|
|
|
details->item[item].count++; |
|
|
|
details->item[item].count++; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#define USB_MAX_READ 8192 |
|
|
|
#define USB_MAX_READ 8192 |
|
|
|
|
|
|
|
|
|
|
|
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, enum usb_cmds cmd, bool readonce) |
|
|
|
int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, const char *end, __maybe_unused enum usb_cmds cmd, bool readonce) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
bool ftdi = (usbdev->usb_type == USB_TYPE_FTDI); |
|
|
|
bool ftdi = (usbdev->usb_type == USB_TYPE_FTDI); |
|
|
@ -1969,7 +2042,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
unsigned int initial_timeout; |
|
|
|
unsigned int initial_timeout; |
|
|
|
double max, done; |
|
|
|
double max, done; |
|
|
|
int bufleft, err, got, tot; |
|
|
|
int bufleft, err, got, tot; |
|
|
|
bool first = true; |
|
|
|
__maybe_unused bool first = true; |
|
|
|
unsigned char *search; |
|
|
|
unsigned char *search; |
|
|
|
int endlen; |
|
|
|
int endlen; |
|
|
|
|
|
|
|
|
|
|
@ -1985,9 +2058,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
*buf = '\0'; |
|
|
|
*buf = '\0'; |
|
|
|
*processed = 0; |
|
|
|
*processed = 0; |
|
|
|
#if DO_USB_STATS |
|
|
|
USB_REJECT(cgpu, MODE_BULK_READ); |
|
|
|
rejected_inc(cgpu); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2012,8 +2084,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
err = libusb_bulk_transfer(usbdev->handle, |
|
|
|
err = libusb_bulk_transfer(usbdev->handle, |
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
ptr, usbbufread, &got, timeout); |
|
|
|
ptr, usbbufread, &got, timeout); |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
cgtime(&tv_finish); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, |
|
|
|
|
|
|
|
MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); |
|
|
|
ptr[got] = '\0'; |
|
|
|
ptr[got] = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); |
|
|
|
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); |
|
|
@ -2040,7 +2113,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
first = false; |
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
|
|
done = tdiff(&tv_finish, &read_start); |
|
|
|
done = tdiff(&tv_finish, &read_start); |
|
|
|
// N.B. this is return LIBUSB_SUCCESS with whatever size has already been read
|
|
|
|
// N.B. this is: return LIBUSB_SUCCESS with whatever size has already been read
|
|
|
|
if (unlikely(done >= max)) |
|
|
|
if (unlikely(done >= max)) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
@ -2075,7 +2148,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
ptr, usbbufread, &got, timeout); |
|
|
|
ptr, usbbufread, &got, timeout); |
|
|
|
cgtime(&tv_finish); |
|
|
|
cgtime(&tv_finish); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, first ? SEQ0 : SEQ1); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, |
|
|
|
|
|
|
|
MODE_BULK_READ, cmd, first ? SEQ0 : SEQ1); |
|
|
|
ptr[got] = '\0'; |
|
|
|
ptr[got] = '\0'; |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); |
|
|
|
USBDEBUG("USB debug: @_usb_read(%s (nodev=%s)) first=%s err=%d%s got=%d ptr='%s' usbbufread=%zu", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), bool_str(first), err, isnodev(err), got, (char *)str_text((char *)ptr), usbbufread); |
|
|
@ -2120,7 +2194,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
first = false; |
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
|
|
done = tdiff(&tv_finish, &read_start); |
|
|
|
done = tdiff(&tv_finish, &read_start); |
|
|
|
// N.B. this is return LIBUSB_SUCCESS with whatever size has already been read
|
|
|
|
// N.B. this is: return LIBUSB_SUCCESS with whatever size has already been read
|
|
|
|
if (unlikely(done >= max)) |
|
|
|
if (unlikely(done >= max)) |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
@ -2136,37 +2210,68 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro |
|
|
|
return err; |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, enum usb_cmds cmd) |
|
|
|
int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *processed, unsigned int timeout, __maybe_unused enum usb_cmds cmd) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
#if DO_USB_STATS |
|
|
|
#if DO_USB_STATS |
|
|
|
struct timeval tv_start, tv_finish; |
|
|
|
struct timeval tv_start; |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
int err, sent; |
|
|
|
struct timeval read_start, tv_finish; |
|
|
|
|
|
|
|
unsigned int initial_timeout; |
|
|
|
|
|
|
|
double max, done; |
|
|
|
|
|
|
|
__maybe_unused bool first = true; |
|
|
|
|
|
|
|
int err, sent, tot; |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: _usb_write(%s (nodev=%s),ep=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), ep, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); |
|
|
|
USBDEBUG("USB debug: _usb_write(%s (nodev=%s),ep=%d,buf='%s',bufsiz=%zu,proc=%p,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), ep, (char *)str_text(buf), bufsiz, processed, timeout, usb_cmdname(cmd)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*processed = 0; |
|
|
|
|
|
|
|
|
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
*processed = 0; |
|
|
|
USB_REJECT(cgpu, MODE_BULK_WRITE); |
|
|
|
#if DO_USB_STATS |
|
|
|
|
|
|
|
rejected_inc(cgpu); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
sent = 0; |
|
|
|
if (timeout == DEVTIMEOUT) |
|
|
|
STATS_TIMEVAL(&tv_start); |
|
|
|
timeout = usbdev->found->timeout; |
|
|
|
err = libusb_bulk_transfer(usbdev->handle, |
|
|
|
|
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
tot = 0; |
|
|
|
(unsigned char *)buf, |
|
|
|
err = LIBUSB_SUCCESS; |
|
|
|
bufsiz, &sent, |
|
|
|
initial_timeout = timeout; |
|
|
|
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); |
|
|
|
max = ((double)timeout) / 1000.0; |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
cgtime(&read_start); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); |
|
|
|
while (bufsiz > 0) { |
|
|
|
|
|
|
|
sent = 0; |
|
|
|
|
|
|
|
STATS_TIMEVAL(&tv_start); |
|
|
|
|
|
|
|
err = libusb_bulk_transfer(usbdev->handle, |
|
|
|
|
|
|
|
usbdev->found->eps[ep].ep, |
|
|
|
|
|
|
|
(unsigned char *)buf, |
|
|
|
|
|
|
|
bufsiz, &sent, timeout); |
|
|
|
|
|
|
|
cgtime(&tv_finish); |
|
|
|
|
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, |
|
|
|
|
|
|
|
MODE_BULK_WRITE, cmd, first ? SEQ0 : SEQ1); |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent); |
|
|
|
USBDEBUG("USB debug: @_usb_write(%s (nodev=%s)) err=%d%s sent=%d", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), sent); |
|
|
|
|
|
|
|
|
|
|
|
*processed = sent; |
|
|
|
tot += sent; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (err) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
buf += sent; |
|
|
|
|
|
|
|
bufsiz -= sent; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
first = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
done = tdiff(&tv_finish, &read_start); |
|
|
|
|
|
|
|
// N.B. this is: return LIBUSB_SUCCESS with whatever size was written
|
|
|
|
|
|
|
|
if (unlikely(done >= max)) |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
timeout = initial_timeout - (done * 1000); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*processed = tot; |
|
|
|
|
|
|
|
|
|
|
|
if (NODEV(err)) |
|
|
|
if (NODEV(err)) |
|
|
|
release_cgpu(cgpu); |
|
|
|
release_cgpu(cgpu); |
|
|
@ -2174,7 +2279,7 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr |
|
|
|
return err; |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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, __maybe_unused enum usb_cmds cmd) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
#if DO_USB_STATS |
|
|
|
#if DO_USB_STATS |
|
|
@ -2186,9 +2291,8 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest |
|
|
|
USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",siz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, siz, timeout, usb_cmdname(cmd)); |
|
|
|
USBDEBUG("USB debug: _usb_transfer(%s (nodev=%s),type=%"PRIu8",req=%"PRIu8",value=%"PRIu16",index=%"PRIu16",siz=%d,timeout=%u,cmd=%s)", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), request_type, bRequest, wValue, wIndex, siz, timeout, usb_cmdname(cmd)); |
|
|
|
|
|
|
|
|
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
#if DO_USB_STATS |
|
|
|
USB_REJECT(cgpu, MODE_CTRL_WRITE); |
|
|
|
rejected_inc(cgpu); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2213,7 +2317,7 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest |
|
|
|
(unsigned char *)buf, (uint16_t)siz, |
|
|
|
(unsigned char *)buf, (uint16_t)siz, |
|
|
|
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); |
|
|
|
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_WRITE, cmd, SEQ0); |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: @_usb_transfer(%s (nodev=%s)) err=%d%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err)); |
|
|
|
USBDEBUG("USB debug: @_usb_transfer(%s (nodev=%s)) err=%d%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err)); |
|
|
|
|
|
|
|
|
|
|
@ -2226,7 +2330,7 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest |
|
|
|
return err; |
|
|
|
return err; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, enum usb_cmds cmd) |
|
|
|
int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, char *buf, int bufsiz, int *amount, unsigned int timeout, __maybe_unused enum usb_cmds cmd) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
struct cg_usb_device *usbdev = cgpu->usbdev; |
|
|
|
#if DO_USB_STATS |
|
|
|
#if DO_USB_STATS |
|
|
@ -2237,9 +2341,8 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe |
|
|
|
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)); |
|
|
|
|
|
|
|
|
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
if (cgpu->usbinfo.nodev) { |
|
|
|
#if DO_USB_STATS |
|
|
|
USB_REJECT(cgpu, MODE_CTRL_READ); |
|
|
|
rejected_inc(cgpu); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
return LIBUSB_ERROR_NO_DEVICE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2251,7 +2354,7 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe |
|
|
|
(unsigned char *)buf, (uint16_t)bufsiz, |
|
|
|
(unsigned char *)buf, (uint16_t)bufsiz, |
|
|
|
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); |
|
|
|
timeout == DEVTIMEOUT ? usbdev->found->timeout : timeout); |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
STATS_TIMEVAL(&tv_finish); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, cmd, SEQ0); |
|
|
|
USB_STATS(cgpu, &tv_start, &tv_finish, err, MODE_CTRL_READ, cmd, SEQ0); |
|
|
|
|
|
|
|
|
|
|
|
USBDEBUG("USB debug: @_usb_transfer_read(%s (nodev=%s)) amt/err=%d%s%s%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), err > 0 ? " = " : BLANK, err > 0 ? bin2hex((unsigned char *)buf, (size_t)err) : BLANK); |
|
|
|
USBDEBUG("USB debug: @_usb_transfer_read(%s (nodev=%s)) amt/err=%d%s%s%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err), err > 0 ? " = " : BLANK, err > 0 ? bin2hex((unsigned char *)buf, (size_t)err) : BLANK); |
|
|
|
|
|
|
|
|
|
|
|