From: Daniel Elstner Date: Wed, 16 Sep 2015 19:31:42 +0000 (+0200) Subject: sysclk-lwla: Clean up open/closed state handling X-Git-Tag: libsigrok-0.4.0~283 X-Git-Url: http://sigrok.org/gitweb/?a=commitdiff_plain;h=c81069b33760f6de36466410ad4bbc9cb762e938;p=libsigrok.git sysclk-lwla: Clean up open/closed state handling 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. --- diff --git a/src/hardware/sysclk-lwla/api.c b/src/hardware/sysclk-lwla/api.c index 928bab75..cee779eb 100644 --- a/src/hardware/sysclk-lwla/api.c +++ b/src/hardware/sysclk-lwla/api.c @@ -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; } diff --git a/src/hardware/sysclk-lwla/protocol.c b/src/hardware/sysclk-lwla/protocol.c index c00a92fd..1c9bca88 100644 --- a/src/hardware/sysclk-lwla/protocol.c +++ b/src/hardware/sysclk-lwla/protocol.c @@ -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); diff --git a/src/hardware/sysclk-lwla/protocol.h b/src/hardware/sysclk-lwla/protocol.h index 61ed4c5f..ce489f71 100644 --- a/src/hardware/sysclk-lwla/protocol.h +++ b/src/hardware/sysclk-lwla/protocol.h @@ -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;