- ret = ftdi_write_data(&devc->ftdic, (unsigned char *)buf, size);
- if (ret < 0)
- sr_err("ftdi_write_data failed: %s",
- ftdi_get_error_string(&devc->ftdic));
- else if ((size_t) ret != size)
- sr_err("ftdi_write_data did not complete write.");
+ if (!devc)
+ return SR_ERR_ARG;
+
+ if (devc->ftdi.must_close) {
+ ret = sigma_ftdi_close(devc);
+ if (ret != SR_OK)
+ return ret;
+ devc->ftdi.must_close = FALSE;
+ }
+
+ return SR_OK;
+}
+
+SR_PRIV int sigma_force_open(const struct sr_dev_inst *sdi)
+{
+ struct dev_context *devc;
+ int ret;
+
+ if (!sdi)
+ return SR_ERR_ARG;
+ devc = sdi->priv;
+ if (!devc)
+ return SR_ERR_ARG;
+
+ ret = sigma_ftdi_open(sdi);
+ if (ret != SR_OK)
+ return ret;
+ devc->ftdi.must_close = FALSE;
+
+ return SR_OK;
+}
+
+SR_PRIV int sigma_force_close(struct dev_context *devc)
+{
+ return sigma_ftdi_close(devc);
+}
+
+/*
+ * BEWARE! Error propagation is important, as are kinds of return values.
+ *
+ * - Raw USB tranport communicates the number of sent or received bytes,
+ * or negative error codes in the external library's(!) range of codes.
+ * - Internal routines at the "sigrok driver level" communicate success
+ * or failure in terms of SR_OK et al error codes.
+ * - Main loop style receive callbacks communicate booleans which arrange
+ * for repeated calls to drive progress during acquisition.
+ *
+ * Careful consideration by maintainers is essential, because all of the
+ * above kinds of values are assignment compatbile from the compiler's
+ * point of view. Implementation errors will go unnoticed at build time.
+ */
+
+static int sigma_read_raw(struct dev_context *devc, void *buf, size_t size)
+{
+ int ret;
+
+ ret = ftdi_read_data(&devc->ftdi.ctx, (unsigned char *)buf, size);
+ if (ret < 0) {
+ sr_err("USB data read failed: %s",
+ ftdi_get_error_string(&devc->ftdi.ctx));
+ }
+
+ return ret;
+}
+
+static int sigma_write_raw(struct dev_context *devc, const void *buf, size_t size)
+{
+ int ret;
+
+ ret = ftdi_write_data(&devc->ftdi.ctx, buf, size);
+ if (ret < 0) {
+ sr_err("USB data write failed: %s",
+ ftdi_get_error_string(&devc->ftdi.ctx));
+ } else if ((size_t)ret != size) {
+ sr_err("USB data write length mismatch.");
+ }