]> sigrok.org Git - libsigrok.git/commitdiff
sysclk-lwla: Attempt initialization three times
authorDaniel Elstner <redacted>
Tue, 22 Dec 2015 14:52:40 +0000 (15:52 +0100)
committerDaniel Elstner <redacted>
Tue, 22 Dec 2015 15:09:39 +0000 (16:09 +0100)
This is a desperate measure to improve the success rate of device
initialization even after it got into a bad state. Combine this
with a reduced USB timeout (1 second) so that if it fails, it fails
quickly. Also ignore USB errors from the initial dummy read of the
device test ID.

src/hardware/sysclk-lwla/api.c
src/hardware/sysclk-lwla/lwla1016.c
src/hardware/sysclk-lwla/lwla1034.c
src/hardware/sysclk-lwla/protocol.h

index 36c9ee608bfc7dc05796437cae9728707ee8e023..20e30d1ecc9c2ba126b9da346987ecf2f8023e50 100644 (file)
@@ -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,54 +305,58 @@ 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) {
-               sr_usb_close(usb);
-               return ret;
-       }
-       /* This delay appears to be necessary for reliable operation. */
-       g_usleep(30 * 1000);
+               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->short_transfer_quirk = FALSE;
-       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);
-               return ret;
        }
-       if (devc->short_transfer_quirk)
+
+       if (ret == SR_OK && devc->short_transfer_quirk)
                sr_warn("Short transfer quirk detected! "
                        "Memory reads will be slow.");
-       return SR_OK;
+       return ret;
 }
 
 /* Shutdown and close device.
index 0e30bf8ec9d9d9ed6a683009b459812bae94f698..61435553951ccf9285712df6c76672da5dcc72b6 100644 (file)
@@ -274,9 +274,7 @@ static int device_init_check(const struct sr_dev_inst *sdi)
 
        const unsigned int test_count = 24;
 
-       ret = lwla_read_reg(sdi->conn, REG_TEST_ID, &value);
-       if (ret != SR_OK)
-               return ret;
+       lwla_read_reg(sdi->conn, REG_TEST_ID, &value);
 
        /* Ignore the value returned by the first read. */
        ret = lwla_read_reg(sdi->conn, REG_TEST_ID, &value);
index 62de549a639b2bd4f2ccec66f14aa7a8fbbc7429..d64641ea9d06b5106312da580a3fc3ca4d5fe293 100644 (file)
@@ -358,9 +358,7 @@ static int device_init_check(const struct sr_dev_inst *sdi)
        uint64_t value;
        int ret;
 
-       ret = read_long_reg(sdi->conn, LREG_TEST_ID, &value);
-       if (ret != SR_OK)
-               return ret;
+       read_long_reg(sdi->conn, LREG_TEST_ID, &value);
 
        /* Ignore the value returned by the first read. */
        ret = read_long_reg(sdi->conn, LREG_TEST_ID, &value);
index adb08b8e0d46630d3890938175cefa16ba46b4a6..5bdc71feff3a5d93595c242b229600b02d70b2bc 100644 (file)
@@ -59,7 +59,7 @@ enum {
 enum {
        USB_CONFIG      = 1,
        USB_INTERFACE   = 0,
-       USB_TIMEOUT_MS  = 3000,
+       USB_TIMEOUT_MS  = 1000,
 };
 
 /** USB device end points.