X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fsysclk-lwla%2Fapi.c;h=d9a6661798aedc6ddfe07bff40332741afb454d9;hb=0a1f7b09b3fa4cc4da29c7acf53717e14b004b63;hp=ba9ca4fa7dd60ae275f094c1336c0cd3f6d18d91;hpb=09ffac33b7af7bba92f2be461dfb8a01e96e2d60;p=libsigrok.git diff --git a/src/hardware/sysclk-lwla/api.c b/src/hardware/sysclk-lwla/api.c index ba9ca4fa..d9a66617 100644 --- a/src/hardware/sysclk-lwla/api.c +++ b/src/hardware/sysclk-lwla/api.c @@ -23,7 +23,7 @@ #include #include #include -#include "libsigrok-internal.h" +#include #include "protocol.h" /* Supported device scan options. @@ -264,7 +264,7 @@ static int drain_usb(struct sr_usb_dev_inst *usb, unsigned int endpoint) do { xfer_len = 0; ret = libusb_bulk_transfer(usb->devhdl, endpoint, - buf, sizeof buf, &xfer_len, + buf, sizeof(buf), &xfer_len, drain_timeout_ms); drained += xfer_len; } while (ret == LIBUSB_SUCCESS && xfer_len != 0); @@ -289,6 +289,7 @@ static int dev_open(struct sr_dev_inst *sdi) struct drv_context *drvc; struct dev_context *devc; struct sr_usb_dev_inst *usb; + int i; int ret; drvc = sdi->driver->context; @@ -304,44 +305,57 @@ static int dev_open(struct sr_dev_inst *sdi) return SR_ERR; } - ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb); - if (ret != SR_OK) - return ret; + /* Try the whole shebang three times, fingers crossed. */ + for (i = 0; i < 3; i++) { + ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb); + if (ret != SR_OK) + return ret; - ret = libusb_set_configuration(usb->devhdl, USB_CONFIG); - if (ret != LIBUSB_SUCCESS) { - sr_err("Failed to set USB configuration: %s.", - libusb_error_name(ret)); - sr_usb_close(usb); - return SR_ERR; - } + ret = libusb_set_configuration(usb->devhdl, USB_CONFIG); + if (ret != LIBUSB_SUCCESS) { + sr_err("Failed to set USB configuration: %s.", + libusb_error_name(ret)); + sr_usb_close(usb); + return SR_ERR; + } - ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); - if (ret != LIBUSB_SUCCESS) { - sr_err("Failed to claim interface: %s.", - libusb_error_name(ret)); - sr_usb_close(usb); - return SR_ERR; - } + ret = libusb_claim_interface(usb->devhdl, USB_INTERFACE); + if (ret != LIBUSB_SUCCESS) { + sr_err("Failed to claim interface: %s.", + libusb_error_name(ret)); + sr_usb_close(usb); + return SR_ERR; + } - ret = drain_usb(usb, EP_REPLY); - if (ret != SR_OK) - return ret; + ret = drain_usb(usb, EP_REPLY); + if (ret != SR_OK) { + sr_usb_close(usb); + return ret; + } + /* This delay appears to be necessary for reliable operation. */ + g_usleep(30 * 1000); - sdi->status = SR_ST_ACTIVE; + sdi->status = SR_ST_ACTIVE; - devc->active_fpga_config = FPGA_NOCONF; - devc->state = STATE_IDLE; + devc->active_fpga_config = FPGA_NOCONF; + devc->short_transfer_quirk = FALSE; + devc->state = STATE_IDLE; - ret = (*devc->model->apply_fpga_config)(sdi); + ret = (*devc->model->apply_fpga_config)(sdi); - if (ret == SR_OK) - ret = (*devc->model->device_init_check)(sdi); + if (ret == SR_OK) + ret = (*devc->model->device_init_check)(sdi); + if (ret == SR_OK) + break; - if (ret != SR_OK) { + /* Rinse and repeat. */ sdi->status = SR_ST_INACTIVE; sr_usb_close(usb); } + + if (ret == SR_OK && devc->short_transfer_quirk) + sr_warn("Short transfer quirk detected! " + "Memory reads will be slow."); return ret; } @@ -474,7 +488,7 @@ static int lookup_index(GVariant *value, const char *const *table, int len) return -1; /* Linear search is fine for very small tables. */ - for (i = 0; i < len; ++i) { + for (i = 0; i < len; i++) { if (strcmp(entry, table[i]) == 0) return i; }