Merge branch 'usbdev' of github.com:ckolivas/cgminer into usbdev
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
diff --git a/usbutils.c b/usbutils.c
index 3c5092b..93ee81d 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -315,6 +315,14 @@ static const char *BLANK = "";
static const char *space = " ";
static const char *nodatareturned = "no data returned ";
+#define IOERR_CHECK(cgpu, err) \
+ if (err == LIBUSB_ERROR_IO) { \
+ cgpu->usbinfo.ioerr_count++; \
+ cgpu->usbinfo.continuous_ioerr_count++; \
+ } else { \
+ cgpu->usbinfo.continuous_ioerr_count = 0; \
+ }
+
#if 0 // enable USBDEBUG - only during development testing
static const char *debug_true_str = "true";
static const char *debug_false_str = "false";
@@ -2066,6 +2074,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
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);
+ IOERR_CHECK(cgpu, err);
+
if (ftdi) {
// first 2 bytes returned are an FTDI status
if (got > 2) {
@@ -2129,6 +2139,8 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro
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);
+ IOERR_CHECK(cgpu, err);
+
if (ftdi) {
// first 2 bytes returned are an FTDI status
if (got > 2) {
@@ -2252,6 +2264,8 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr
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);
+ IOERR_CHECK(cgpu, err);
+
tot += sent;
if (err)
@@ -2319,6 +2333,8 @@ int _usb_transfer(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRequest
USBDEBUG("USB debug: @_usb_transfer(%s (nodev=%s)) err=%d%s", cgpu->drv->name, bool_str(cgpu->usbinfo.nodev), err, isnodev(err));
+ IOERR_CHECK(cgpu, err);
+
if (buf)
free(buf);
@@ -2356,6 +2372,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)) 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);
+ IOERR_CHECK(cgpu, err);
+
if (err > 0) {
*amount = err;
err = 0;
@@ -2368,12 +2386,14 @@ int _usb_transfer_read(struct cgpu_info *cgpu, uint8_t request_type, uint8_t bRe
void usb_cleanup()
{
struct cgpu_info *cgpu;
+ int count;
int i;
hotplug_time = 0;
nmsleep(10);
+ count = 0;
for (i = 0; i < total_devices; i++) {
cgpu = devices[i];
switch (cgpu->drv->drv_id) {
@@ -2383,11 +2403,40 @@ void usb_cleanup()
case DRIVER_ICARUS:
case DRIVER_AVALON:
release_cgpu(cgpu);
+ count++;
break;
default:
break;
}
}
+
+ /*
+ * Must attempt to wait for the resource thread to release coz
+ * during a restart it won't automatically release them in linux
+ */
+ if (count) {
+ struct timeval start, now;
+
+ cgtime(&start);
+ while (42) {
+ nmsleep(50);
+
+ mutex_lock(&cgusbres_lock);
+
+ if (!res_work_head)
+ break;
+
+ cgtime(&now);
+ if (tdiff(&now, &start) > 0.366) {
+ applog(LOG_WARNING,
+ "usb_cleanup gave up waiting for resource thread");
+ break;
+ }
+
+ mutex_unlock(&cgusbres_lock);
+ }
+ mutex_unlock(&cgusbres_lock);
+ }
}
void usb_initialise()
@@ -2825,7 +2874,6 @@ fila:
// exceeding this timeout means it would probably never succeed anyway
struct timespec timeout = { 0, 10000000 };
- // Wait forever since we shoud be the one who has it
if (semtimedop(sem, sops, 1, &timeout)) {
applog(LOG_ERR,
"SEM: %s USB failed to release '%s' err (%d) %s",
diff --git a/usbutils.h b/usbutils.h
index 03c15ca..a7b79d1 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -171,6 +171,8 @@ struct cg_usb_info {
bool nodev;
int nodev_count;
struct timeval last_nodev;
+ uint32_t ioerr_count;
+ uint32_t continuous_ioerr_count;
};
enum usb_cmds {