Commit 546be35cc7545a1c8b33e3fa6a7a41d7f10e2f44

Con Kolivas 2013-05-18T13:16:17

Merge branch 'icarus-dev' of github.com:ckolivas/cgminer into icarus-dev

diff --git a/cgminer.c b/cgminer.c
index 086b0d9..1654f9c 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -7052,6 +7052,10 @@ static void *hotplug_thread(void __maybe_unused *userdata)
 			new_devices = 0;
 			new_threads = 0;
 
+#ifdef USE_ICARUS
+			icarus_drv.drv_detect();
+#endif
+
 #ifdef USE_BFLSC
 			bflsc_drv.drv_detect();
 #endif
diff --git a/driver-bflsc.c b/driver-bflsc.c
index 9c1528c..e0cb161 100644
--- a/driver-bflsc.c
+++ b/driver-bflsc.c
@@ -568,8 +568,6 @@ static void __bflsc_initialise(struct cgpu_info *bflsc)
 {
 	int err;
 
-// TODO: this is a standard BFL FPGA Initialisation
-// it probably will need changing ...
 // TODO: does x-link bypass the other device FTDI? (I think it does)
 //	So no initialisation required except for the master device?
 
@@ -588,7 +586,7 @@ static void __bflsc_initialise(struct cgpu_info *bflsc)
 
 	// Set data control
 	err = usb_transfer(bflsc, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
-				FTDI_VALUE_DATA, bflsc->usbdev->found->interface, C_SETDATA);
+				FTDI_VALUE_DATA_BAS, bflsc->usbdev->found->interface, C_SETDATA);
 
 	applog(LOG_DEBUG, "%s%i: setdata got err %d",
 		bflsc->drv->name, bflsc->device_id, err);
@@ -597,8 +595,8 @@ static void __bflsc_initialise(struct cgpu_info *bflsc)
 		return;
 
 	// Set the baud
-	err = usb_transfer(bflsc, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD,
-				(FTDI_INDEX_BAUD & 0xff00) | bflsc->usbdev->found->interface,
+	err = usb_transfer(bflsc, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_BAS,
+				(FTDI_INDEX_BAUD_BAS & 0xff00) | bflsc->usbdev->found->interface,
 				C_SETBAUD);
 
 	applog(LOG_DEBUG, "%s%i: setbaud got err %d",
diff --git a/driver-bitforce.c b/driver-bitforce.c
index 7b4361b..c845285 100644
--- a/driver-bitforce.c
+++ b/driver-bitforce.c
@@ -101,7 +101,7 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
 
 	// Set data control
 	err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_DATA,
-				FTDI_VALUE_DATA, bitforce->usbdev->found->interface, C_SETDATA);
+				FTDI_VALUE_DATA_BFL, bitforce->usbdev->found->interface, C_SETDATA);
 	if (opt_debug)
 		applog(LOG_DEBUG, "%s%i: setdata got err %d",
 			bitforce->drv->name, bitforce->device_id, err);
@@ -110,8 +110,8 @@ static void bitforce_initialise(struct cgpu_info *bitforce, bool lock)
 		goto failed;
 
 	// Set the baud
-	err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD,
-				(FTDI_INDEX_BAUD & 0xff00) | bitforce->usbdev->found->interface,
+	err = usb_transfer(bitforce, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_BFL,
+				(FTDI_INDEX_BAUD_BFL & 0xff00) | bitforce->usbdev->found->interface,
 				C_SETBAUD);
 	if (opt_debug)
 		applog(LOG_DEBUG, "%s%i: setbaud got err %d",
diff --git a/driver-icarus.c b/driver-icarus.c
index a4b26c6..850b65a 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -215,12 +215,91 @@ static int option_offset = -1;
 
 struct device_drv icarus_drv;
 
-static void icarus_initialise(struct cgpu_info *icarus, int baud)
+static void transfer(struct cgpu_info *icarus, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, enum usb_cmds cmd)
+{
+	int err;
+
+	err = usb_transfer(icarus, request_type, bRequest, wValue, wIndex, cmd);
+
+	applog(LOG_DEBUG, "%s%i: %s got err %d",
+			icarus->drv->name, icarus->device_id,
+			usb_cmdname(cmd), err);
+}
+
+// TODO: handle baud
+static void icarus_initialise(struct cgpu_info *icarus, __maybe_unused int baud)
 {
 	if (icarus->usbinfo.nodev)
 		return;
 
-	if (baud) {
+	switch (icarus->usbdev->ident) {
+		case IDENT_BLT:
+		case IDENT_LLT:
+			// Reset
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, FTDI_VALUE_LATENCY,
+				 icarus->usbdev->found->interface, C_RESET);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Reset
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET,
+				 icarus->usbdev->found->interface, C_RESET);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Set data control
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_DATA, FTDI_VALUE_DATA_BLT,
+				 icarus->usbdev->found->interface, C_SETDATA);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Set the baud
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_BAUD, FTDI_VALUE_BAUD_BLT,
+				 (FTDI_INDEX_BAUD_BLT & 0xff00) | icarus->usbdev->found->interface,
+				 C_SETBAUD);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Set Modem Control
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_MODEM, FTDI_VALUE_MODEM,
+				 icarus->usbdev->found->interface, C_SETMODEM);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Set Flow Control
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_FLOW, FTDI_VALUE_FLOW,
+				 icarus->usbdev->found->interface, C_SETFLOW);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Clear any sent data
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_TX,
+				 icarus->usbdev->found->interface, C_PURGETX);
+
+			if (icarus->usbinfo.nodev)
+				return;
+
+			// Clear any received data
+			transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_PURGE_RX,
+				 icarus->usbdev->found->interface, C_PURGERX);
+
+			break;
+		case IDENT_ICA:
+			break;
+		case IDENT_AMU:
+			break;
+		case IDENT_CMR:
+			break;
+		default:
+			quit(1, "icarus_intialise() called with invalid %s%i ident=%d",
+				icarus->drv->name, icarus->device_id,
+				icarus->usbdev->ident);
 	}
 }
 
@@ -251,6 +330,9 @@ static int icarus_get_nonce(struct cgpu_info *icarus, unsigned char *buf, struct
 
 	cgtime(tv_start);
 	while (true) {
+		if (icarus->usbinfo.nodev)
+			return ICA_NONCE_ERROR;
+
 		cgtime(&read_start);
 		err = usb_read_timeout(icarus, (char *)buf, read_amount, &amt, ICARUS_WAIT_TIMEOUT, C_GETRESULTS);
 		cgtime(&read_finish);
diff --git a/usbutils.c b/usbutils.c
index 5b43850..96f27b0 100644
--- a/usbutils.c
+++ b/usbutils.c
@@ -1020,6 +1020,8 @@ union semun {
 // and thus it is best to always display them
 static bool cgminer_usb_lock_bd(struct device_drv *drv, uint8_t bus_number, uint8_t device_address)
 {
+	applog(LOG_DEBUG, "USB lock %s %d-%d", drv->name, (int)bus_number, (int)device_address);
+
 #ifdef WIN32
 	struct cgpu_info *cgpu;
 	HANDLE usbMutex;
@@ -1180,6 +1182,8 @@ static bool cgminer_usb_lock(struct device_drv *drv, libusb_device *dev)
 // and thus it is best to always display them
 static void cgminer_usb_unlock_bd(struct device_drv *drv, uint8_t bus_number, uint8_t device_address)
 {
+	applog(LOG_DEBUG, "USB unlock %s %d-%d", drv->name, (int)bus_number, (int)device_address);
+
 #ifdef WIN32
 	HANDLE usbMutex;
 	char name[64];
@@ -1253,6 +1257,8 @@ static void cgminer_usb_unlock(struct device_drv *drv, libusb_device *dev)
 
 static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
 {
+	applog(LOG_DEBUG, "USB free %s", cgusb->found->name);
+
 	if (cgusb->serial_string && cgusb->serial_string != BLANK)
 		free(cgusb->serial_string);
 
@@ -1273,6 +1279,9 @@ static struct cg_usb_device *free_cgusb(struct cg_usb_device *cgusb)
 
 void usb_uninit(struct cgpu_info *cgpu)
 {
+	applog(LOG_DEBUG, "USB uninit %s%i",
+			cgpu->drv->name, cgpu->device_id);
+
 	// May have happened already during a failed initialisation
 	//  if release_cgpu() was called due to a USB NODEV(err)
 	if (!cgpu->usbdev)
@@ -1288,6 +1297,9 @@ static void release_cgpu(struct cgpu_info *cgpu)
 	struct cgpu_info *lookcgpu;
 	int i;
 
+	applog(LOG_DEBUG, "USB release %s%i",
+			cgpu->drv->name, cgpu->device_id);
+
 	// It has already been done
 	if (cgpu->usbinfo.nodev)
 		return;
@@ -1677,16 +1689,16 @@ static struct usb_find_devices *usb_check(__maybe_unused struct device_drv *drv,
 		return usb_check_each(DRV_BITFORCE, drv, dev);
 #endif
 
-#ifdef USE_ICARUS
-	if (drv->drv_id == DRIVER_ICARUS)
-		return usb_check_each(DRV_ICARUS, drv, dev);
-#endif
-
 #ifdef USE_MODMINER
 	if (drv->drv_id == DRIVER_MODMINER)
 		return usb_check_each(DRV_MODMINER, drv, dev);
 #endif
 
+#ifdef USE_ICARUS
+	if (drv->drv_id == DRIVER_ICARUS)
+		return usb_check_each(DRV_ICARUS, drv, dev);
+#endif
+
 #ifdef USE_AVALON
 	if (drv->drv_id == DRIVER_AVALON)
 		return usb_check_each(DRV_AVALON, drv, dev);
@@ -2193,6 +2205,7 @@ void usb_cleanup()
 			case DRIVER_BFLSC:
 			case DRIVER_BITFORCE:
 			case DRIVER_MODMINER:
+			case DRIVER_ICARUS:
 			case DRIVER_AVALON:
 				release_cgpu(cgpu);
 				break;
@@ -2301,6 +2314,12 @@ void usb_initialise()
 					found = true;
 				}
 #endif
+#ifdef USE_ICARUS
+				if (!found && strcasecmp(ptr, icarus_drv.name) == 0) {
+					drv_count[icarus_drv.drv_id].limit = lim;
+					found = true;
+				}
+#endif
 #ifdef USE_AVALON
 				if (!found && strcasecmp(ptr, avalon_drv.name) == 0) {
 					drv_count[avalon_drv.drv_id].limit = lim;
diff --git a/usbutils.h b/usbutils.h
index 74c166e..5e50c72 100644
--- a/usbutils.h
+++ b/usbutils.h
@@ -20,18 +20,28 @@
 #define FTDI_REQUEST_FLOW ((uint8_t)2)
 #define FTDI_REQUEST_BAUD ((uint8_t)3)
 #define FTDI_REQUEST_DATA ((uint8_t)4)
+#define FTDI_REQUEST_LATENCY ((uint8_t)9)
 
 #define FTDI_VALUE_RESET 0
 #define FTDI_VALUE_PURGE_RX 1
 #define FTDI_VALUE_PURGE_TX 2
+#define FTDI_VALUE_LATENCY 1
+
+// Baud
+#define FTDI_VALUE_BAUD_BFL 0xc068
+#define FTDI_INDEX_BAUD_BFL 0x0200
+#define FTDI_VALUE_BAUD_BAS FTDI_VALUE_BAUD_BFL
+#define FTDI_INDEX_BAUD_BAS FTDI_INDEX_BAUD_BFL
+// LLT = BLT (same code)
+#define FTDI_VALUE_BAUD_BLT 0x001a
+#define FTDI_INDEX_BAUD_BLT 0x0000
+
+// Data control
+#define FTDI_VALUE_DATA_BFL 0
+#define FTDI_VALUE_DATA_BAS FTDI_VALUE_DATA_BFL
+// LLT = BLT (same code)
+#define FTDI_VALUE_DATA_BLT 8
 
-// baud with a 0 divisor is 120,000,000/10
-//#define FTDI_VALUE_BAUD (0)
-//#define FTDI_INDEX_BAUD (0)
-#define FTDI_VALUE_BAUD 0xc068
-#define FTDI_INDEX_BAUD 0x0200
-
-#define FTDI_VALUE_DATA 0
 #define FTDI_VALUE_FLOW 0
 #define FTDI_VALUE_MODEM 0x0303