}
/**
- * Close the specified device.
+ * Close the specified device instance.
+ *
+ * If the device instance is not open (sdi->status != SR_ST_ACTIVE),
+ * SR_ERR_DEV_CLOSED will be returned and no closing will be attempted.
+ *
+ * Note: sdi->status will be set to SR_ST_INACTIVE, regardless of whether
+ * there are any errors during closing of the device instance (any errors
+ * will be reported via error code and log message, though).
*
* @param sdi Device instance to use. Must not be NULL.
*
- * @return SR_OK upon success, a negative error code upon errors.
+ * @retval SR_OK Success.
+ * @retval SR_ERR_ARG Invalid arguments.
+ * @retval SR_ERR_DEV_CLOSED Device instance was not active.
+ * @retval SR_ERR Other error.
*
* @since 0.2.0
*/
int ret;
if (!sdi || !sdi->driver || !sdi->driver->dev_close)
- return SR_ERR;
+ return SR_ERR_ARG;
if (sdi->status != SR_ST_ACTIVE) {
sr_err("%s: Device instance not active, can't close.",
return SR_ERR_DEV_CLOSED;
}
- sr_dbg("%s: Closing device.", sdi->driver->name)
+ sdi->status = SR_ST_INACTIVE;
+
+ sr_dbg("%s: Closing device instance.", sdi->driver->name);
ret = sdi->driver->dev_close(sdi);
devc = sdi->priv;
- ftdi_usb_close(&devc->ftdic);
-
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return (ftdi_usb_close(&devc->ftdic) == 0) ? SR_OK : SR_ERR;
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
struct dev_context *devc;
devc = sdi->priv;
+
if (devc->config_dirty)
/* Some configuration changes were queued up but didn't
* get sent to the device, likely because we were never
{
(void)sdi;
- sdi->status = SR_ST_INACTIVE;
-
return SR_OK;
}
beaglelogic_munmap(devc);
beaglelogic_close(devc);
- sdi->status = SR_ST_INACTIVE;
-
return SR_OK;
}
if ((ret = libusb_release_interface(usb->devhdl, 0)))
sr_err("Failed to release interface 0: %s.\n", libusb_error_name(ret));
- else
- sr_dbg("Successfully released interface 0.\n");
if (!ret && devc->detached_kernel_driver) {
- if ((ret = libusb_attach_kernel_driver(usb->devhdl, 0))) {
+ if ((ret = libusb_attach_kernel_driver(usb->devhdl, 0)))
sr_err("Failed to attach kernel driver: %s.\n",
libusb_error_name(ret));
- } else {
+ else
devc->detached_kernel_driver = 0;
- sr_dbg("Successfully attached kernel driver.\n");
- }
}
libusb_close(usb->devhdl);
- sdi->status = SR_ST_INACTIVE;
-
- return ret;
+ return (ret == 0) ? SR_OK : SR_ERR;
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
devc = sdi->priv;
- if (devc->ftdic && (ret = ftdi_usb_close(devc->ftdic)) < 0)
+ if (!devc->ftdic)
+ return SR_ERR_BUG;
+
+ if ((ret = ftdi_usb_close(devc->ftdic)) < 0)
sr_err("Failed to close FTDI device (%d): %s.",
ret, ftdi_get_error_string(devc->ftdic));
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return (ret == 0) ? SR_OK : SR_ERR;
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
static int dev_close(struct sr_dev_inst *sdi)
{
- sdi->status = SR_ST_INACTIVE;
+ (void)sdi;
return SR_OK;
}
usb = sdi->conn;
if (!usb->devhdl)
- return SR_ERR;
+ return SR_ERR_BUG;
sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
devc = sdi->priv;
- if (devc->ftdic) {
- ftdi_usb_close(devc->ftdic);
- ftdi_free(devc->ftdic);
- devc->ftdic = NULL;
- }
+ if (!devc->ftdic)
+ return SR_ERR_BUG;
- sdi->status = SR_ST_INACTIVE;
+ ftdi_usb_close(devc->ftdic);
+ ftdi_free(devc->ftdic);
+ devc->ftdic = NULL;
return SR_OK;
}
usb = sdi->conn;
if (!usb->devhdl)
- return SR_ERR;
+ return SR_ERR_BUG;
sr_info("fx2lafw: Closing device on %d.%d (logical) / %s (physical) interface %d.",
usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
{
struct dev_context *devc;
- std_serial_dev_close(sdi);
+ devc = sdi->priv;
- if ((devc = sdi->priv))
- devc->model = METRAHIT_NONE;
+ devc->model = METRAHIT_NONE;
- return SR_OK;
+ return std_serial_dev_close(sdi);
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
struct sr_scpi_dev_inst *scpi;
scpi = sdi->conn;
- if (scpi) {
- if (sr_scpi_close(scpi) < 0)
- return SR_ERR;
- sdi->status = SR_ST_INACTIVE;
- }
- return SR_OK;
+ if (!scpi)
+ return SR_ERR_BUG;
+
+ return sr_scpi_close(scpi);
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
static int dev_close(struct sr_dev_inst *sdi)
{
- sr_scpi_close(sdi->conn);
-
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return sr_scpi_close(sdi->conn);
}
static int check_channel_group(struct dev_context *devc,
sr_scpi_close(scpi);
- sdi->status = SR_ST_INACTIVE;
-
return SR_OK;
}
ieee1284_release(sdi->conn);
ieee1284_close(sdi->conn);
- sdi->status = SR_ST_INACTIVE;
-
return SR_OK;
}
usb = sdi->conn;
if (!usb->devhdl)
- return SR_OK;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
devc = sdi->priv;
- sdi->status = SR_ST_INACTIVE;
-
return scanaplus_close(devc);
}
usb = sdi->conn;
if (!usb->devhdl)
- /* Nothing to do. */
- return SR_OK;
+ return SR_ERR_BUG;
/* This allows a frontend to configure the device without ever
* doing an acquisition step. */
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
usb = sdi->conn;
if (!usb->devhdl)
- /* Nothing to do. */
- return SR_OK;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, LASCAR_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
}
if (!usb->devhdl)
- return SR_ERR;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, 0);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
-
return SR_OK;
}
static int dev_close(struct sr_dev_inst *sdi)
{
- sr_scpi_close(sdi->conn);
-
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return sr_scpi_close(sdi->conn);
}
static int config_get(uint32_t key, GVariant **data,
modbus = sdi->conn;
- if (modbus) {
- devc = sdi->priv;
- if (devc->expecting_registers) {
- /* Wait for the last data that was requested from the device. */
- uint16_t registers[devc->expecting_registers];
- sr_modbus_read_holding_registers(modbus, -1,
- devc->expecting_registers, registers);
- }
+ if (!modbus)
+ return SR_ERR_BUG;
- maynuo_m97_set_bit(modbus, PC1, 0);
+ devc = sdi->priv;
- if (sr_modbus_close(modbus) < 0)
- return SR_ERR;
- sdi->status = SR_ST_INACTIVE;
+ if (devc->expecting_registers) {
+ /* Wait for the last data that was requested from the device. */
+ uint16_t registers[devc->expecting_registers];
+ sr_modbus_read_holding_registers(modbus, -1,
+ devc->expecting_registers, registers);
}
- return SR_OK;
+ maynuo_m97_set_bit(modbus, PC1, 0);
+
+ return sr_modbus_close(modbus);
}
static int config_get(uint32_t key, GVariant **data, const struct sr_dev_inst *sdi,
devc = sdi->priv;
- sdi->status = SR_ST_INACTIVE;
-
return p_ols_close(devc);
}
scpi = sdi->conn;
devc = sdi->priv;
+ if (!scpi)
+ return SR_ERR_BUG;
+
if (devc->model->series->protocol == PROTOCOL_V2)
rigol_ds_config_set(sdi, ":KEY:LOCK DISABLE");
- if (scpi) {
- if (sr_scpi_close(scpi) < 0)
- return SR_ERR;
- sdi->status = SR_ST_INACTIVE;
- }
-
- return SR_OK;
+ return sr_scpi_close(scpi);
}
static int analog_frame_size(const struct sr_dev_inst *sdi)
static int dev_close(struct sr_dev_inst *sdi)
{
- sr_scpi_close(sdi->conn);
-
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return sr_scpi_close(sdi->conn);
}
static int config_get(uint32_t key, GVariant **data,
static int dev_close(struct sr_dev_inst *sdi)
{
- struct sr_usb_dev_inst *usb = sdi->conn;
-
- sr_usb_close(usb);
-
- sdi->status = SR_ST_INACTIVE;
+ sr_usb_close(sdi->conn);
return SR_OK;
}
struct sr_usb_dev_inst *usb;
usb = sdi->conn;
+
if (!usb->devhdl)
- return SR_ERR;
+ return SR_ERR_BUG;
sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
devc = sdi->priv;
scpi = sdi->conn;
- if (scpi) {
- if (devc->beeper_was_set)
- scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_ENABLE);
- scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
- sr_scpi_close(scpi);
- sdi->status = SR_ST_INACTIVE;
- }
- return SR_OK;
+ if (!scpi)
+ return SR_ERR_BUG;
+
+ if (devc->beeper_was_set)
+ scpi_cmd(sdi, devc->device->commands, SCPI_CMD_BEEPER_ENABLE);
+ scpi_cmd(sdi, devc->device->commands, SCPI_CMD_LOCAL);
+
+ return sr_scpi_close(scpi);
}
static void clear_helper(void *priv)
return ret;
}
-/* Shutdown and close device.
- */
+/* Shutdown and close device. */
static int dev_close(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
return SR_ERR_BUG;
}
- sdi->status = SR_ST_INACTIVE;
-
/* Download of the shutdown bitstream, if any. */
ret = (*devc->model->apply_fpga_config)(sdi);
if (ret != SR_OK)
sr_warn("Unable to shut down device.");
libusb_release_interface(usb->devhdl, USB_INTERFACE);
+
sr_usb_close(usb);
- return ret;
+ return SR_OK;
}
/* Check whether the device options contain a specific key.
struct sr_usb_dev_inst *usb;
usb = sdi->conn;
+
if (!usb->devhdl)
- /* Nothing to do. */
- return SR_OK;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, 0);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
static int dev_close(struct sr_dev_inst *sdi)
{
- /* TODO */
+ (void)sdi;
- sdi->status = SR_ST_INACTIVE;
+ /* TODO */
return SR_OK;
}
struct sr_usb_dev_inst *usb;
usb = sdi->conn;
+
if (!usb->devhdl)
- /* Nothing to do. */
- return SR_OK;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
usb = sdi->conn;
if (!usb->devhdl)
- /* Nothing to do. */
- return SR_OK;
+ return SR_ERR_BUG;
libusb_release_interface(usb->devhdl, VICTOR_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
static int dev_close(struct sr_dev_inst *sdi)
{
- sr_scpi_close(sdi->conn);
-
- sdi->status = SR_ST_INACTIVE;
-
- return SR_OK;
+ return sr_scpi_close(sdi->conn);
}
/**
usb = sdi->conn;
if (!usb->devhdl)
- return SR_ERR;
+ return SR_ERR_BUG;
sr_info("Closing device on %d.%d (logical) / %s (physical) interface %d.",
usb->bus, usb->address, sdi->connection_id, USB_INTERFACE);
libusb_reset_device(usb->devhdl);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
- sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
* This function can be used to implement the dev_close() driver API
* callback in drivers that use a serial port.
*
- * After closing the port, the status field of the given sdi is set
- * to SR_ST_INACTIVE.
- *
* @retval SR_OK Success.
* @retval SR_ERR_ARG Invalid arguments.
+ * @retval SR_ERR Serial port close failed.
*/
SR_PRIV int std_serial_dev_close(struct sr_dev_inst *sdi)
{
struct sr_serial_dev_inst *serial;
- sdi->status = SR_ST_INACTIVE;
-
- serial = sdi->conn;
- if (!serial) {
- sr_err("%s: Can't close invalid serial port.", sdi->driver->name);
+ if (!sdi || !sdi->conn)
return SR_ERR_ARG;
- }
- serial_close(serial);
+ serial = sdi->conn;
- return SR_OK;
+ return serial_close(serial);
}
/**