Commit f1ba6b4b authored by Uwe Hermann's avatar Uwe Hermann

sr_dev_close(): Set status to SR_ST_INACTIVE.

This ensures consistent checks and log messages across all drivers
and reduces the per-driver boilerplate.
parent 7e463623
......@@ -585,11 +585,21 @@ SR_API int sr_dev_open(struct sr_dev_inst *sdi)
}
/**
* 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
*/
......@@ -598,7 +608,7 @@ SR_API int sr_dev_close(struct sr_dev_inst *sdi)
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.",
......@@ -606,7 +616,9 @@ SR_API int sr_dev_close(struct sr_dev_inst *sdi)
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);
......
......@@ -156,11 +156,7 @@ static int dev_close(struct sr_dev_inst *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,
......
......@@ -421,6 +421,7 @@ static int dev_close(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
......
......@@ -137,8 +137,6 @@ static int dev_close(struct sr_dev_inst *sdi)
{
(void)sdi;
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -168,8 +168,6 @@ static int dev_close(struct sr_dev_inst *sdi)
beaglelogic_munmap(devc);
beaglelogic_close(devc);
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -134,24 +134,18 @@ static int dev_close(struct sr_dev_inst *sdi)
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,
......
......@@ -287,13 +287,14 @@ static int dev_close(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,
......
......@@ -189,7 +189,7 @@ static int dev_open(struct sr_dev_inst *sdi)
static int dev_close(struct sr_dev_inst *sdi)
{
sdi->status = SR_ST_INACTIVE;
(void)sdi;
return SR_OK;
}
......
......@@ -382,14 +382,13 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -319,13 +319,12 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -438,14 +438,13 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -334,12 +334,11 @@ static int dev_close(struct sr_dev_inst *sdi)
{
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,
......
......@@ -106,13 +106,11 @@ static int dev_close(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,
......
......@@ -142,11 +142,7 @@ static int dev_open(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,
......
......@@ -219,8 +219,6 @@ static int dev_close(struct sr_dev_inst *sdi)
sr_scpi_close(scpi);
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -282,8 +282,6 @@ static int dev_close(struct sr_dev_inst *sdi)
ieee1284_release(sdi->conn);
ieee1284_close(sdi->conn);
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -242,13 +242,12 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -221,8 +221,6 @@ static int dev_close(struct sr_dev_inst *sdi)
devc = sdi->priv;
sdi->status = SR_ST_INACTIVE;
return scanaplus_close(devc);
}
......
......@@ -183,8 +183,7 @@ static int dev_close(struct sr_dev_inst *sdi)
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. */
......@@ -195,7 +194,6 @@ static int dev_close(struct sr_dev_inst *sdi)
libusb_release_interface(usb->devhdl, USB_INTERFACE);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -108,13 +108,11 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -337,15 +337,13 @@ static int dev_close(struct sr_dev_inst *sdi)
}
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;
}
......
......@@ -146,11 +146,7 @@ static int dev_open(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,
......
......@@ -215,23 +215,21 @@ static int dev_close(struct sr_dev_inst *sdi)
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,
......
......@@ -420,8 +420,6 @@ static int dev_close(struct sr_dev_inst *sdi)
devc = sdi->priv;
sdi->status = SR_ST_INACTIVE;
return p_ols_close(devc);
}
......
......@@ -456,16 +456,13 @@ static int dev_close(struct sr_dev_inst *sdi)
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)
......
......@@ -167,11 +167,7 @@ static int dev_open(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,
......
......@@ -210,11 +210,7 @@ static int dev_open(struct sr_dev_inst *sdi)
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;
}
......
......@@ -379,15 +379,15 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -277,15 +277,15 @@ static int dev_close(struct sr_dev_inst *sdi)
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)
......
......@@ -324,8 +324,7 @@ static int dev_open(struct sr_dev_inst *sdi)
return ret;
}
/* Shutdown and close device.
*/
/* Shutdown and close device. */
static int dev_close(struct sr_dev_inst *sdi)
{
struct dev_context *devc;
......@@ -342,17 +341,16 @@ static int dev_close(struct sr_dev_inst *sdi)
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.
......
......@@ -171,14 +171,13 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -108,9 +108,9 @@ static int dev_open(struct sr_dev_inst *sdi)
static int dev_close(struct sr_dev_inst *sdi)
{
/* TODO */
(void)sdi;
sdi->status = SR_ST_INACTIVE;
/* TODO */
return SR_OK;
}
......
......@@ -136,14 +136,13 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -131,13 +131,11 @@ static int dev_close(struct sr_dev_inst *sdi)
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;
}
......
......@@ -152,11 +152,7 @@ static int dev_open(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);
}
/**
......
......@@ -319,7 +319,7 @@ static int dev_close(struct sr_dev_inst *sdi)
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);
......@@ -327,7 +327,6 @@ static int dev_close(struct sr_dev_inst *sdi)
libusb_reset_device(usb->devhdl);
libusb_close(usb->devhdl);
usb->devhdl = NULL;
sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
......
......@@ -174,27 +174,20 @@ SR_PRIV int std_serial_dev_open(struct sr_dev_inst *sdi)
* 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);
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment