Commit 8520f430b1ae003cce1225e213e2415aaa8bc1e9

Con Kolivas 2013-05-30T16:33:01

Merge branch 'usbdev' of github.com:ckolivas/cgminer into usbdev

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 {