/*
- * This file is part of the sigrok project.
+ * This file is part of the libsigrok project.
*
* Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Olivier Fauchon <olivier@aixmarseille.com>
#include "libsigrok.h"
#include "libsigrok-internal.h"
-/* Message logging helpers with driver-specific prefix string. */
-#define DRIVER_LOG_DOMAIN "demo: "
-#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args)
-#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args)
-#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args)
-#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args)
-#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args)
-#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args)
+/* Message logging helpers with subsystem-specific prefix string. */
+#define LOG_PREFIX "demo: "
+#define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
+#define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
+#define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
+#define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
+#define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
+#define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
/* TODO: Number of probes should be configurable. */
#define NUM_PROBES 8
static int hw_init(struct sr_context *sr_ctx)
{
- return std_hw_init(sr_ctx, di, DRIVER_LOG_DOMAIN);
+ return std_hw_init(sr_ctx, di, LOG_PREFIX);
}
static GSList *hw_scan(GSList *options)
sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL);
if (!sdi) {
- sr_err("%s: sr_dev_inst_new failed", __func__);
- return 0;
+ sr_err("Device instance creation failed.");
+ return NULL;
}
sdi->driver = di;
devices = g_slist_append(devices, sdi);
drvc->instances = g_slist_append(drvc->instances, sdi);
- /* TODO: 'devc' is never g_free()'d? */
if (!(devc = g_try_malloc(sizeof(struct dev_context)))) {
- sr_err("%s: devc malloc failed", __func__);
- return SR_ERR_MALLOC;
+ sr_err("Device context malloc failed.");
+ return NULL;
}
devc->sdi = sdi;
{
(void)sdi;
- /* Nothing needed so far. */
+ sdi->status = SR_ST_ACTIVE;
return SR_OK;
}
{
(void)sdi;
- /* Nothing needed so far. */
+ sdi->status = SR_ST_INACTIVE;
return SR_OK;
}
static int hw_cleanup(void)
{
- /* Nothing needed so far. */
- return SR_OK;
+ GSList *l;
+ struct sr_dev_inst *sdi;
+ struct drv_context *drvc;
+ int ret = SR_OK;
+
+ if (!(drvc = di->priv))
+ return SR_OK;
+
+ /* Properly close and free all devices. */
+ for (l = drvc->instances; l; l = l->next) {
+ if (!(sdi = l->data)) {
+ /* Log error, but continue cleaning up the rest. */
+ sr_err("%s: sdi was NULL, continuing", __func__);
+ ret = SR_ERR_BUG;
+ continue;
+ }
+ sr_dev_inst_free(sdi);
+ }
+ g_slist_free(drvc->instances);
+ drvc->instances = NULL;
+
+ return ret;
}
static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi)
}
break;
default:
- return SR_ERR_ARG;
+ return SR_ERR_NA;
}
return SR_OK;
struct dev_context *const devc = sdi->priv;
+ if (sdi->status != SR_ST_ACTIVE)
+ return SR_ERR_DEV_CLOSED;
+
if (id == SR_CONF_SAMPLERATE) {
devc->cur_samplerate = g_variant_get_uint64(data);
sr_dbg("%s: setting samplerate to %" PRIu64, __func__,
sr_dbg("%s: setting pattern to %d",
__func__, devc->sample_generator);
} else {
- ret = SR_ERR;
+ ret = SR_ERR_NA;
}
return ret;
*data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings));
break;
default:
- return SR_ERR_ARG;
+ return SR_ERR_NA;
}
return SR_OK;
{
struct dev_context *const devc = sdi->priv;
+ if (sdi->status != SR_ST_ACTIVE)
+ return SR_ERR_DEV_CLOSED;
+
devc->cb_data = cb_data;
devc->samples_counter = 0;
40, receive_data, devc);
/* Send header packet to the session bus. */
- std_session_send_df_header(cb_data, DRIVER_LOG_DOMAIN);
+ std_session_send_df_header(cb_data, LOG_PREFIX);
/* We use this timestamp to decide how many more samples to send. */
devc->starttime = g_get_monotonic_time();
sr_session_source_remove_channel(devc->channel);
g_io_channel_shutdown(devc->channel, FALSE, NULL);
+ g_io_channel_unref(devc->channel);
+ devc->channel = NULL;
/* Send last packet. */
packet.type = SR_DF_END;