]> sigrok.org Git - libsigrok.git/commitdiff
sysclk-lwla: Clean up open/closed state handling
authorDaniel Elstner <redacted>
Wed, 16 Sep 2015 19:31:42 +0000 (21:31 +0200)
committerDaniel Elstner <redacted>
Wed, 16 Sep 2015 21:37:58 +0000 (23:37 +0200)
Use states SR_ST_ACTIVE and SR_ST_INACTIVE to indicate that the
device is open or closed, respectively. Do not use any of the
other state values. Improve the robustness of the open and close
methods in face of errors. Introduce a separate flag to indicate
that a running acquisition should be canceled.

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

index 928bab75bf58d9a5b8aa513633bf000f066c1956..cee779eb4820861e6cf5a68de2cbfc810ddd21d4 100644 (file)
@@ -193,7 +193,10 @@ static int dev_open(struct sr_dev_inst *sdi)
                sr_err("Driver was not initialized.");
                return SR_ERR;
        }
-
+       if (sdi->status != SR_ST_INACTIVE) {
+               sr_err("Device already open.");
+               return SR_ERR;
+       }
        usb = sdi->conn;
 
        ret = sr_usb_open(drvc->sr_ctx->libusb_ctx, usb);
@@ -204,44 +207,50 @@ static int dev_open(struct sr_dev_inst *sdi)
        if (ret < 0) {
                sr_err("Failed to claim interface: %s.",
                        libusb_error_name(ret));
+               sr_usb_close(usb);
                return SR_ERR;
        }
-
-       sdi->status = SR_ST_INITIALIZING;
+       sdi->status = SR_ST_ACTIVE;
 
        ret = lwla_init_device(sdi);
-
-       if (ret == SR_OK)
-               sdi->status = SR_ST_ACTIVE;
-
+       if (ret != SR_OK) {
+               sr_usb_close(usb);
+               sdi->status = SR_ST_INACTIVE;
+       }
        return ret;
 }
 
 static int dev_close(struct sr_dev_inst *sdi)
 {
        struct sr_usb_dev_inst *usb;
+       struct dev_context *devc;
+       int ret;
 
        if (!di->context) {
                sr_err("Driver was not initialized.");
                return SR_ERR;
        }
-
        usb = sdi->conn;
-       if (!usb->devhdl)
+       devc = sdi->priv;
+
+       if (sdi->status == SR_ST_INACTIVE)
                return SR_OK;
 
+       if (devc && devc->acquisition) {
+               sr_err("Attempt to close device during acquisition.");
+               return SR_ERR;
+       }
        sdi->status = SR_ST_INACTIVE;
 
        /* Trigger download of the shutdown bitstream. */
-       if (lwla_set_clock_config(sdi) != SR_OK)
+       ret = lwla_set_clock_config(sdi);
+       if (ret != SR_OK)
                sr_err("Unable to shut down device.");
 
        libusb_release_interface(usb->devhdl, USB_INTERFACE);
-       libusb_close(usb->devhdl);
+       sr_usb_close(usb);
 
-       usb->devhdl = NULL;
-
-       return SR_OK;
+       return ret;
 }
 
 static int cleanup(const struct sr_dev_driver *di)
@@ -565,6 +574,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
        if (!acq)
                return SR_ERR_MALLOC;
 
+       devc->cancel_requested = FALSE;
        devc->stopping_in_progress = FALSE;
        devc->transfer_error = FALSE;
 
@@ -599,15 +609,18 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data)
 
 static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data)
 {
+       struct dev_context *devc;
+
        (void)cb_data;
+       devc = sdi->priv;
 
        if (sdi->status != SR_ST_ACTIVE)
                return SR_ERR_DEV_CLOSED;
 
-       sr_dbg("Stopping acquisition.");
-
-       sdi->status = SR_ST_STOPPING;
-
+       if (devc->acquisition && !devc->cancel_requested) {
+               devc->cancel_requested = TRUE;
+               sr_dbg("Stopping acquisition.");
+       }
        return SR_OK;
 }
 
index c00a92fd6919b42886b3842b8cd207c5b2fa324f..1c9bca885e08f3af60949aa8f807d1003331015b 100644 (file)
@@ -305,7 +305,7 @@ static void process_capture_length(const struct sr_dev_inst *sdi)
 
        sr_dbg("%zu words in capture buffer.", acq->mem_addr_fill);
 
-       if (acq->mem_addr_fill > 0 && sdi->status == SR_ST_ACTIVE)
+       if (acq->mem_addr_fill > 0 && !devc->cancel_requested)
                issue_read_start(sdi);
        else
                issue_read_end(sdi);
@@ -599,8 +599,7 @@ static void end_acquisition(struct sr_dev_inst *sdi)
 
        lwla_free_acquisition_state(devc->acquisition);
        devc->acquisition = NULL;
-
-       sdi->status = SR_ST_ACTIVE;
+       devc->cancel_requested = FALSE;
 }
 
 /* USB output transfer completion callback.
@@ -631,7 +630,7 @@ static void LIBUSB_CALL receive_transfer_out(struct libusb_transfer *transfer)
                        submit_transfer(devc, devc->acquisition->xfer_in);
                        break;
                case STATE_STOP_CAPTURE:
-                       if (sdi->status == SR_ST_ACTIVE)
+                       if (!devc->cancel_requested)
                                request_capture_length(sdi);
                        else
                                end_acquisition(sdi);
@@ -972,7 +971,7 @@ SR_PRIV int lwla_receive_data(int fd, int revents, void *cb_data)
 
        /* If no event flags are set the timeout must have expired. */
        if (revents == 0 && devc->state == STATE_STATUS_WAIT) {
-               if (sdi->status == SR_ST_STOPPING)
+               if (devc->cancel_requested)
                        issue_stop_capture(sdi);
                else
                        request_capture_status(sdi);
index 61ed4c5f4d6388904e6cafa5422b28ac01b1fd8d..ce489f71810b81fe3e66ed637be736865e174aee 100644 (file)
@@ -241,6 +241,9 @@ struct dev_context {
        /** Trigger slope configuration setting. */
        enum signal_edge cfg_trigger_slope;
 
+       /** Whether a running acquisition should be canceled. */
+       gboolean cancel_requested;
+
        /* Indicates that stopping the acquisition is currently in progress. */
        gboolean stopping_in_progress;