From 1c64f3b6218b864a69f5d926b777a05bd1992e61 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 4 Jun 2013 13:17:57 +1000 Subject: [PATCH 1/4] usb set FTDI latency higher to minimise status bytes --- driver-bflsc.c | 39 +++++++++++++++++++++++++++++++++++++++ driver-icarus.c | 17 +++++++++++------ usbutils.c | 48 +++++++++++++++--------------------------------- usbutils.h | 4 ++++ 4 files changed, 69 insertions(+), 39 deletions(-) diff --git a/driver-bflsc.c b/driver-bflsc.c index e77d1cc4..10232323 100644 --- a/driver-bflsc.c +++ b/driver-bflsc.c @@ -289,6 +289,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 +564,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 +600,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 +814,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 +910,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 +922,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 +930,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..f22cbbdc 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) { @@ -2105,23 +2113,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro done = tdiff(&tv_finish, &read_start); // 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) + if (timeout <= 0) break; - if (!got && sleep_time) { - if (timeout <= sleep_time) - sleep_time = timeout - 1; - timeout -= sleep_time; - nmsleep(sleep_time); - } } *processed = tot; @@ -2139,9 +2133,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) { @@ -2204,18 +2195,9 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro done = tdiff(&tv_finish, &read_start); // 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) + if (timeout <= 0) break; - if (!got && sleep_time) { - if (timeout <= sleep_time) - sleep_time = timeout - 1; - timeout -= sleep_time; - nmsleep(sleep_time); - } } *processed = tot; 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 From cab2dd92ab38478aae5c41cb9d159cf4b9fc1c0e Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 4 Jun 2013 13:30:05 +1000 Subject: [PATCH 2/4] compile warning - remove unused max --- usbutils.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/usbutils.c b/usbutils.c index f22cbbdc..79cfe425 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2035,7 +2035,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro #endif struct timeval read_start, tv_finish; unsigned int initial_timeout; - double max, done; + double done; int bufleft, err, got, tot; __maybe_unused bool first = true; unsigned char *search; @@ -2069,7 +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; - max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { if (ftdi) @@ -2133,7 +2132,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; - max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { if (ftdi) @@ -2217,7 +2215,7 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr #endif struct timeval read_start, tv_finish; unsigned int initial_timeout; - double max, done; + double done; __maybe_unused bool first = true; int err, sent, tot; @@ -2237,7 +2235,6 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr tot = 0; err = LIBUSB_SUCCESS; initial_timeout = timeout; - max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufsiz > 0) { sent = 0; @@ -2266,11 +2263,8 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr done = tdiff(&tv_finish, &read_start); // N.B. this is: return LIBUSB_SUCCESS with whatever size was written - if (unlikely(done >= max)) - break; - timeout = initial_timeout - (done * 1000); - if (!timeout) + if (timeout <= 0) break; } From 4d749ff44b07a91bd17d6f3e3eca11d2297b4f89 Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 4 Jun 2013 13:43:23 +1000 Subject: [PATCH 3/4] restore max code - since timeout is unsigned --- usbutils.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/usbutils.c b/usbutils.c index 79cfe425..9a7cca69 100644 --- a/usbutils.c +++ b/usbutils.c @@ -2035,7 +2035,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro #endif struct timeval read_start, tv_finish; unsigned int initial_timeout; - double done; + double max, done; int bufleft, err, got, tot; __maybe_unused bool first = true; unsigned char *search; @@ -2069,6 +2069,7 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro bufleft = bufsiz; err = LIBUSB_SUCCESS; initial_timeout = timeout; + max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { if (ftdi) @@ -2112,8 +2113,10 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro done = tdiff(&tv_finish, &read_start); // 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 <= 0) + if (!timeout) break; } @@ -2132,6 +2135,7 @@ 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; + max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufleft > 0) { if (ftdi) @@ -2193,8 +2197,10 @@ int _usb_read(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pro done = tdiff(&tv_finish, &read_start); // 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 <= 0) + if (!timeout) break; } @@ -2215,7 +2221,7 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr #endif struct timeval read_start, tv_finish; unsigned int initial_timeout; - double done; + double max, done; __maybe_unused bool first = true; int err, sent, tot; @@ -2235,6 +2241,7 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr tot = 0; err = LIBUSB_SUCCESS; initial_timeout = timeout; + max = ((double)timeout) / 1000.0; cgtime(&read_start); while (bufsiz > 0) { sent = 0; @@ -2263,8 +2270,10 @@ int _usb_write(struct cgpu_info *cgpu, int ep, char *buf, size_t bufsiz, int *pr done = tdiff(&tv_finish, &read_start); // N.B. this is: return LIBUSB_SUCCESS with whatever size was written + if (unlikely(done >= max)) + break; timeout = initial_timeout - (done * 1000); - if (timeout <= 0) + if (!timeout) break; } From a16f51fb2e2a5f4acd149193a8ffa82723915b8c Mon Sep 17 00:00:00 2001 From: Kano Date: Tue, 4 Jun 2013 22:37:00 +1000 Subject: [PATCH 4/4] correct bflsc BFLSC_BUFSIZ max calculation --- driver-bflsc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/driver-bflsc.c b/driver-bflsc.c index 10232323..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)