diff --git a/device.c b/device.c index 21ddebca..84d3d663 100644 --- a/device.c +++ b/device.c @@ -290,3 +290,22 @@ SR_API int sr_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, return ret; } + +SR_API GSList *sr_dev_inst_list(const struct sr_dev_driver *driver) +{ + + if (driver && driver->dev_list) + return driver->dev_list(); + else + return NULL; +} + +SR_API int sr_dev_inst_clear(const struct sr_dev_driver *driver) +{ + + if (driver && driver->dev_clear) + return driver->dev_clear(); + else + return SR_OK; +} + diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index a1dd2072..ed32e6a5 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -406,7 +406,7 @@ static int bin2bitbang(const char *filename, return SR_OK; } -static void clear_instances(void) +static int clear_instances(void) { GSList *l; struct sr_dev_inst *sdi; @@ -431,6 +431,7 @@ static void clear_instances(void) g_slist_free(drvc->instances); drvc->instances = NULL; + return SR_OK; } static int hw_init(void) @@ -531,6 +532,15 @@ free: return NULL; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = adi->priv; + + return drvc->instances; +} + static int upload_firmware(int firmware_idx, struct dev_context *devc) { int ret; @@ -1455,6 +1465,8 @@ SR_PRIV struct sr_dev_driver asix_sigma_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/chronovu-la8/api.c b/hardware/chronovu-la8/api.c index a7fff108..012ad6f1 100644 --- a/hardware/chronovu-la8/api.c +++ b/hardware/chronovu-la8/api.c @@ -41,7 +41,7 @@ static const uint16_t usb_pids[] = { static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, void *cb_data); -static void clear_instances(void) +static int clear_instances(void) { GSList *l; struct sr_dev_inst *sdi; @@ -66,6 +66,7 @@ static void clear_instances(void) g_slist_free(drvc->instances); drvc->instances = NULL; + return SR_OK; } static int hw_init(void) @@ -186,6 +187,15 @@ err_free_nothing: return NULL; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = cdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -519,6 +529,8 @@ SR_PRIV struct sr_dev_driver chronovu_la8_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/demo/demo.c b/hardware/demo/demo.c index 3e3150af..ba440a3d 100644 --- a/hardware/demo/demo.c +++ b/hardware/demo/demo.c @@ -192,6 +192,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = ddi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { /* Avoid compiler warnings. */ @@ -537,6 +546,7 @@ SR_PRIV struct sr_dev_driver demo_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/fx2lafw/fx2lafw.c b/hardware/fx2lafw/fx2lafw.c index 44cc9aef..d519db6f 100644 --- a/hardware/fx2lafw/fx2lafw.c +++ b/hardware/fx2lafw/fx2lafw.c @@ -511,6 +511,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = fdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -1046,6 +1055,8 @@ SR_PRIV struct sr_dev_driver fx2lafw_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/genericdmm/api.c b/hardware/genericdmm/api.c index 42136017..035ffedf 100644 --- a/hardware/genericdmm/api.c +++ b/hardware/genericdmm/api.c @@ -219,6 +219,52 @@ static GSList *default_scan(GSList *options) return devices; } +static int clear_instances(void) +{ + GSList *l; + struct sr_dev_inst *sdi; + struct dev_context *devc; + struct drv_context *drvc; + + if (!(drvc = gdi->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("genericdmm: sdi was NULL, continuing."); + continue; + } + if (!(devc = sdi->priv)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("genericdmm: sdi->priv was NULL, continuing."); + continue; + } + + if (devc->profile) { + switch (devc->profile->transport) { + case DMM_TRANSPORT_USBHID: + /* TODO */ + sr_usb_dev_inst_free(devc->usb); + break; + case DMM_TRANSPORT_SERIAL: + if (devc->serial && devc->serial->fd != -1) + serial_close(devc->serial->fd); + sr_serial_dev_inst_free(devc->serial); + break; + } + } + + sr_dev_inst_free(sdi); + } + + g_slist_free(drvc->instances); + drvc->instances = NULL; + + return SR_OK; +} + static int hw_init(void) { struct drv_context *drvc; @@ -338,6 +384,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = gdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -347,14 +402,13 @@ static int hw_dev_open(struct sr_dev_inst *sdi) return SR_ERR_BUG; } - sr_dbg("genericdmm: Opening serial port '%s'.", devc->serial->port); - switch (devc->profile->transport) { case DMM_TRANSPORT_USBHID: /* TODO */ break; case DMM_TRANSPORT_SERIAL: /* TODO: O_NONBLOCK? */ + sr_dbg("genericdmm: Opening serial port '%s'.", devc->serial->port); devc->serial->fd = serial_open(devc->serial->port, O_RDWR | O_NONBLOCK); if (devc->serial->fd == -1) { sr_err("genericdmm: Couldn't open serial port '%s'.", @@ -397,46 +451,8 @@ static int hw_dev_close(struct sr_dev_inst *sdi) static int hw_cleanup(void) { - GSList *l; - struct sr_dev_inst *sdi; - struct dev_context *devc; - struct drv_context *drvc; - if (!(drvc = gdi->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("genericdmm: sdi was NULL, continuing."); - continue; - } - if (!(devc = sdi->priv)) { - /* Log error, but continue cleaning up the rest. */ - sr_err("genericdmm: sdi->priv was NULL, continuing."); - continue; - } - - if (devc->profile) { - switch (devc->profile->transport) { - case DMM_TRANSPORT_USBHID: - /* TODO */ - sr_usb_dev_inst_free(devc->usb); - break; - case DMM_TRANSPORT_SERIAL: - if (devc->serial && devc->serial->fd != -1) - serial_close(devc->serial->fd); - sr_serial_dev_inst_free(devc->serial); - break; - } - } - - sr_dev_inst_free(sdi); - } - - g_slist_free(drvc->instances); - drvc->instances = NULL; + clear_instances(); if (genericdmm_usb_context) libusb_exit(genericdmm_usb_context); @@ -610,6 +626,8 @@ SR_PRIV struct sr_dev_driver genericdmm_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/hantek-dso/api.c b/hardware/hantek-dso/api.c index c1828b44..64dc0f98 100644 --- a/hardware/hantek-dso/api.c +++ b/hardware/hantek-dso/api.c @@ -221,7 +221,7 @@ static int configure_probes(const struct sr_dev_inst *sdi) } /* Properly close and free all devices. */ -static void clear_instances(void) +static int clear_instances(void) { struct sr_dev_inst *sdi; struct drv_context *drvc; @@ -250,6 +250,7 @@ static void clear_instances(void) g_slist_free(drvc->instances); drvc->instances = NULL; + return SR_OK; } static int hw_init(void) @@ -346,6 +347,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = hdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -904,6 +914,8 @@ SR_PRIV struct sr_dev_driver hantek_dso_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = clear_instances, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/openbench-logic-sniffer/ols.c b/hardware/openbench-logic-sniffer/ols.c index 7a89d775..5b13931c 100644 --- a/hardware/openbench-logic-sniffer/ols.c +++ b/hardware/openbench-logic-sniffer/ols.c @@ -519,6 +519,15 @@ hw_init_free_ports: return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = odi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -1082,6 +1091,8 @@ SR_PRIV struct sr_dev_driver ols_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = hw_cleanup, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/hardware/zeroplus-logic-cube/zeroplus.c b/hardware/zeroplus-logic-cube/zeroplus.c index 72e044bc..7f6196a8 100644 --- a/hardware/zeroplus-logic-cube/zeroplus.c +++ b/hardware/zeroplus-logic-cube/zeroplus.c @@ -226,7 +226,7 @@ static int configure_probes(const struct sr_dev_inst *sdi) return SR_OK; } -static void clear_instances(void) +static int clear_instances(void) { GSList *l; struct sr_dev_inst *sdi; @@ -250,6 +250,7 @@ static void clear_instances(void) g_slist_free(drvc->instances); drvc->instances = NULL; + return SR_OK; } /* @@ -354,6 +355,15 @@ static GSList *hw_scan(GSList *options) return devices; } +static GSList *hw_dev_list(void) +{ + struct drv_context *drvc; + + drvc = zdi->priv; + + return drvc->instances; +} + static int hw_dev_open(struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -687,6 +697,8 @@ SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info = { .init = hw_init, .cleanup = hw_cleanup, .scan = hw_scan, + .dev_list = hw_dev_list, + .dev_clear = hw_cleanup, .dev_open = hw_dev_open, .dev_close = hw_dev_close, .info_get = hw_info_get, diff --git a/libsigrok.h b/libsigrok.h index 75f6c3c2..728a63f5 100644 --- a/libsigrok.h +++ b/libsigrok.h @@ -482,6 +482,8 @@ struct sr_dev_driver { int (*init) (void); int (*cleanup) (void); GSList *(*scan) (GSList *options); + GSList *(*dev_list) (void); + int (*dev_clear) (void); /* Device-specific */ int (*dev_open) (struct sr_dev_inst *sdi); diff --git a/proto.h b/proto.h index ce61d009..6536c5a4 100644 --- a/proto.h +++ b/proto.h @@ -56,6 +56,8 @@ SR_API int sr_dev_trigger_set(const struct sr_dev_inst *sdi, int probenum, SR_API gboolean sr_dev_has_hwcap(const struct sr_dev_inst *sdi, int hwcap); SR_API int sr_dev_config_set(const struct sr_dev_inst *sdi, int hwcap, const void *value); +SR_API GSList *sr_dev_inst_list(const struct sr_dev_driver *driver); +SR_API int sr_dev_inst_clear(const struct sr_dev_driver *driver); /*--- filter.c --------------------------------------------------------------*/