diff --git a/cgminer.c b/cgminer.c index 086b0d94..1654f9c6 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 9c1528ca..e0cb161e 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 7b4361bb..c845285e 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 a4b26c6a..850b65a5 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 5b438509..96f27b0d 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 74c166e3..5e50c72f 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