diff --git a/driver-bflsc.c b/driver-bflsc.c index e77d1cc4..1f813e94 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -32,10 +32,11 @@ /* * With Firmware 1.0.0 and a result queue of 20 the Max is: - * header = 9 - * 64+1+32+1+1+(1+8)*8+1 per line = 172 * 20 + * inprocess = 12 + * max count = 9 + * 64+1+24+1+1+(1+8)*8+1 per line = 164 * 20 * OK = 3 - * Total: 3452 + * Total: 3304 */ #define BFLSC_BUFSIZ (0x1000) @@ -289,6 +290,11 @@ struct SaveString { #define BAJ_RES_TIME 100 #define BFLSC_MAX_SLEEP 2000 +#define BAJ_LATENCY LATENCY_STD +#define BAL_LATENCY LATENCY_STD +#define BAS_LATENCY LATENCY_STD +#define BAM_LATENCY 2 + #define BFLSC_TEMP_SLEEPMS 5 #define BFLSC_QUE_SIZE 20 #define BFLSC_QUE_FULL_ENOUGH 13 @@ -559,6 +565,25 @@ static bool bflsc_qres(struct cgpu_info *bflsc, char *buf, size_t bufsiz, int de return readok; } +static void __set_latency(struct cgpu_info *bflsc) +{ + int err; + + if (bflsc->usbinfo.nodev) + return; + + // Latency + err = usb_transfer(bflsc, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, + bflsc->usbdev->found->latency, + bflsc->usbdev->found->interface, C_LATENCY); + + applog(LOG_DEBUG, "%s%i: latency got err %d", + bflsc->drv->name, bflsc->device_id, err); + + if (bflsc->usbinfo.nodev) + return; +} + static void __bflsc_initialise(struct cgpu_info *bflsc) { int err; @@ -576,6 +601,11 @@ static void __bflsc_initialise(struct cgpu_info *bflsc) applog(LOG_DEBUG, "%s%i: reset got err %d", bflsc->drv->name, bflsc->device_id, err); + if (bflsc->usbinfo.nodev) + return; + + __set_latency(bflsc); + if (bflsc->usbinfo.nodev) return; @@ -785,6 +815,7 @@ static bool bflsc_detect_one(struct libusb_device *dev, struct usb_find_devices int init_sleep, init_count; bool ident_first; char *newname; + uint16_t latency; struct cgpu_info *bflsc = calloc(1, sizeof(*bflsc)); @@ -880,6 +911,7 @@ reinit: sc_info->scan_sleep_time = BAS_SCAN_TIME; sc_info->results_sleep_time = BAS_RES_TIME; sc_info->default_ms_work = BAS_WORK_TIME; + latency = BAS_LATENCY; /* When getinfo() "FREQUENCY: [UNKNOWN]" is fixed - * use 'freq * engines' to estimate. @@ -891,6 +923,7 @@ reinit: sc_info->results_sleep_time = BAM_RES_TIME; sc_info->default_ms_work = BAM_WORK_TIME; bflsc->usbdev->ident = IDENT_BAM; + latency = BAM_LATENCY; } else { if (sc_info->sc_devs[0].engines < 34) { // 16 * 2 + 2 newname = BFLSC_JALAPENO; @@ -898,15 +931,22 @@ reinit: sc_info->results_sleep_time = BAJ_RES_TIME; sc_info->default_ms_work = BAJ_WORK_TIME; bflsc->usbdev->ident = IDENT_BAJ; + latency = BAJ_LATENCY; } else if (sc_info->sc_devs[0].engines < 130) { // 16 * 8 + 2 newname = BFLSC_LITTLESINGLE; sc_info->scan_sleep_time = BAL_SCAN_TIME; sc_info->results_sleep_time = BAL_RES_TIME; sc_info->default_ms_work = BAL_WORK_TIME; bflsc->usbdev->ident = IDENT_BAL; + latency = BAL_LATENCY; } } + if (latency != bflsc->usbdev->found->latency) { + bflsc->usbdev->found->latency = latency; + __set_latency(bflsc); + } + for (i = 0; i < sc_info->sc_count; i++) sc_info->sc_devs[i].ms_work = sc_info->default_ms_work; diff --git a/driver-icarus.c b/driver-icarus.c index ccd762b8..d782a71e 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -256,12 +256,9 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud) case IDENT_LLT: case IDENT_CMR1: case IDENT_CMR2: - // Latency - transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, FTDI_VALUE_LATENCY, - icarus->usbdev->found->interface, C_LATENCY); - - if (icarus->usbinfo.nodev) - return; + if (icarus->usbdev->found->latency == LATENCY_UNUSED) + quit(1, "%s: cgid %d invalid latency (UNUSED)", + icarus->drv->name, icarus->cgminer_id); // Reset transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_RESET, FTDI_VALUE_RESET, @@ -270,6 +267,14 @@ static void icarus_initialise(struct cgpu_info *icarus, int baud) if (icarus->usbinfo.nodev) return; + // Latency + transfer(icarus, FTDI_TYPE_OUT, FTDI_REQUEST_LATENCY, + icarus->usbdev->found->latency, + icarus->usbdev->found->interface, C_LATENCY); + + 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); diff --git a/usbutils.c b/usbutils.c index 257a2cab..9a7cca69 100644 --- a/usbutils.c +++ b/usbutils.c @@ -149,6 +149,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = BFLSC_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(bas_eps), .eps = bas_eps }, #endif @@ -165,6 +166,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = BITFORCE_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(bfl_eps), .eps = bfl_eps }, #endif @@ -179,6 +181,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 1, .timeout = MODMINER_TIMEOUT_MS, + .latency = LATENCY_UNUSED, .epcount = ARRAY_SIZE(mmq_eps), .eps = mmq_eps }, #endif @@ -193,6 +196,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = AVALON_TIMEOUT_MS, + .latency = 10, .epcount = ARRAY_SIZE(ava_eps), .eps = ava_eps }, #endif @@ -207,6 +211,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_UNUSED, .epcount = ARRAY_SIZE(ica_eps), .eps = ica_eps }, { @@ -219,6 +224,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_UNUSED, .epcount = ARRAY_SIZE(amu_eps), .eps = amu_eps }, { @@ -232,6 +238,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(llt_eps), .eps = llt_eps }, // For any that don't match the above "BLT" @@ -245,6 +252,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(llt_eps), .eps = llt_eps }, { @@ -258,6 +266,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(cmr1_eps), .eps = cmr1_eps }, { @@ -271,6 +280,7 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 0, .timeout = ICARUS_TIMEOUT_MS, + .latency = LATENCY_STD, .epcount = ARRAY_SIZE(cmr2_eps), .eps = cmr2_eps }, #endif @@ -287,10 +297,11 @@ static struct usb_find_devices find_dev[] = { .config = 1, .interface = 1, .timeout = 100, + .latency = LATENCY_UNUSED, .epcount = 0, .eps = NULL }, #endif - { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, NULL } + { DRV_LAST, NULL, 0, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, NULL } }; #ifdef USE_BFLSC @@ -2023,7 +2034,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro struct timeval tv_start; #endif struct timeval read_start, tv_finish; - unsigned int initial_timeout, sleep_time; + unsigned int initial_timeout; double max, done; int bufleft, err, got, tot; __maybe_unused bool first = true; @@ -2058,9 +2069,6 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro bufleft = bufsiz; err = LIBUSB_SUCCESS; initial_timeout = timeout; - sleep_time = initial_timeout / 2; - if (sleep_time > USB_READ_MINPOLL) - sleep_time = USB_READ_MINPOLL; max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { @@ -2107,21 +2115,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro // N.B. this is: return LIBUSB_SUCCESS with whatever size has already been read if (unlikely(done >= max)) break; - - /* Controversial. Even though libusb gives the device - * a timeout, many devices (eg ftdi) simply time out - * after only 1ms making this function poll every ms - * if we don't sleep here, but do it only if we're not - * receiving any data. */ timeout = initial_timeout - (done * 1000); if (!timeout) break; - if (!got && sleep_time) { - if (timeout <= sleep_time) - sleep_time = timeout - 1; - timeout -= sleep_time; - nmsleep(sleep_time); - } } *processed = tot; @@ -2139,9 +2135,6 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro endlen = strlen(end); err = LIBUSB_SUCCESS; initial_timeout = timeout; - sleep_time = initial_timeout / 2; - if (sleep_time > USB_READ_MINPOLL) - sleep_time = USB_READ_MINPOLL; max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { @@ -2206,16 +2199,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro // N.B. this is: return LIBUSB_SUCCESS with whatever size has already been read if (unlikely(done >= max)) break; - timeout = initial_timeout - (done * 1000); if (!timeout) break; - if (!got && sleep_time) { - if (timeout <= sleep_time) - sleep_time = timeout - 1; - timeout -= sleep_time; - nmsleep(sleep_time); - } } *processed = tot; @@ -2286,7 +2272,6 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr // N.B. this is: return LIBUSB_SUCCESS with whatever size was written if (unlikely(done >= max)) break; - timeout = initial_timeout - (done * 1000); if (!timeout) break; diff --git a/usbutils.h b/usbutils.h index 77a202c8..5ff90c22 100644 --- a/usbutils.h +++ b/usbutils.h @@ -140,10 +140,14 @@ struct usb_find_devices { int config; int interface; unsigned int timeout; + uint16_t latency; int epcount; struct usb_endpoints *eps; }; +#define LATENCY_UNUSED 0 +#define LATENCY_STD 40 + enum usb_types { USB_TYPE_STD = 0, USB_TYPE_FTDI