sr/drivers: add API calls sr_dev_inst_list() and sr_dev_inst_clear()

These are used to list the device instances currently known to the driver,
and clear that list.

Drivers that don't necessarily clear their list of instances on every scan,
such as genericdmm, need to provide these to the frontend to keep instance
management sane.
This commit is contained in:
Bert Vermeulen 2012-08-06 00:59:25 +02:00
parent 014359e329
commit 811deee4af
11 changed files with 166 additions and 45 deletions

View File

@ -290,3 +290,22 @@ SR_API int sr_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
return ret; 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;
}

View File

@ -406,7 +406,7 @@ static int bin2bitbang(const char *filename,
return SR_OK; return SR_OK;
} }
static void clear_instances(void) static int clear_instances(void)
{ {
GSList *l; GSList *l;
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
@ -431,6 +431,7 @@ static void clear_instances(void)
g_slist_free(drvc->instances); g_slist_free(drvc->instances);
drvc->instances = NULL; drvc->instances = NULL;
return SR_OK;
} }
static int hw_init(void) static int hw_init(void)
@ -531,6 +532,15 @@ free:
return NULL; 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) static int upload_firmware(int firmware_idx, struct dev_context *devc)
{ {
int ret; int ret;
@ -1455,6 +1465,8 @@ SR_PRIV struct sr_dev_driver asix_sigma_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = clear_instances,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -41,7 +41,7 @@ static const uint16_t usb_pids[] = {
static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi, static int hw_dev_acquisition_stop(const struct sr_dev_inst *sdi,
void *cb_data); void *cb_data);
static void clear_instances(void) static int clear_instances(void)
{ {
GSList *l; GSList *l;
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
@ -66,6 +66,7 @@ static void clear_instances(void)
g_slist_free(drvc->instances); g_slist_free(drvc->instances);
drvc->instances = NULL; drvc->instances = NULL;
return SR_OK;
} }
static int hw_init(void) static int hw_init(void)
@ -186,6 +187,15 @@ err_free_nothing:
return NULL; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -519,6 +529,8 @@ SR_PRIV struct sr_dev_driver chronovu_la8_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = clear_instances,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -192,6 +192,15 @@ static GSList *hw_scan(GSList *options)
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
/* Avoid compiler warnings. */ /* Avoid compiler warnings. */
@ -537,6 +546,7 @@ SR_PRIV struct sr_dev_driver demo_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -511,6 +511,15 @@ static GSList *hw_scan(GSList *options)
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -1046,6 +1055,8 @@ SR_PRIV struct sr_dev_driver fx2lafw_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = clear_instances,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -219,6 +219,52 @@ static GSList *default_scan(GSList *options)
return devices; 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) static int hw_init(void)
{ {
struct drv_context *drvc; struct drv_context *drvc;
@ -338,6 +384,15 @@ static GSList *hw_scan(GSList *options)
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -347,14 +402,13 @@ static int hw_dev_open(struct sr_dev_inst *sdi)
return SR_ERR_BUG; return SR_ERR_BUG;
} }
sr_dbg("genericdmm: Opening serial port '%s'.", devc->serial->port);
switch (devc->profile->transport) { switch (devc->profile->transport) {
case DMM_TRANSPORT_USBHID: case DMM_TRANSPORT_USBHID:
/* TODO */ /* TODO */
break; break;
case DMM_TRANSPORT_SERIAL: case DMM_TRANSPORT_SERIAL:
/* TODO: O_NONBLOCK? */ /* 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); devc->serial->fd = serial_open(devc->serial->port, O_RDWR | O_NONBLOCK);
if (devc->serial->fd == -1) { if (devc->serial->fd == -1) {
sr_err("genericdmm: Couldn't open serial port '%s'.", 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) static int hw_cleanup(void)
{ {
GSList *l;
struct sr_dev_inst *sdi;
struct dev_context *devc;
struct drv_context *drvc;
if (!(drvc = gdi->priv)) clear_instances();
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;
if (genericdmm_usb_context) if (genericdmm_usb_context)
libusb_exit(genericdmm_usb_context); libusb_exit(genericdmm_usb_context);
@ -610,6 +626,8 @@ SR_PRIV struct sr_dev_driver genericdmm_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = clear_instances,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -221,7 +221,7 @@ static int configure_probes(const struct sr_dev_inst *sdi)
} }
/* Properly close and free all devices. */ /* Properly close and free all devices. */
static void clear_instances(void) static int clear_instances(void)
{ {
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
struct drv_context *drvc; struct drv_context *drvc;
@ -250,6 +250,7 @@ static void clear_instances(void)
g_slist_free(drvc->instances); g_slist_free(drvc->instances);
drvc->instances = NULL; drvc->instances = NULL;
return SR_OK;
} }
static int hw_init(void) static int hw_init(void)
@ -346,6 +347,15 @@ static GSList *hw_scan(GSList *options)
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -904,6 +914,8 @@ SR_PRIV struct sr_dev_driver hantek_dso_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = clear_instances,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -519,6 +519,15 @@ hw_init_free_ports:
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -1082,6 +1091,8 @@ SR_PRIV struct sr_dev_driver ols_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = hw_cleanup,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -226,7 +226,7 @@ static int configure_probes(const struct sr_dev_inst *sdi)
return SR_OK; return SR_OK;
} }
static void clear_instances(void) static int clear_instances(void)
{ {
GSList *l; GSList *l;
struct sr_dev_inst *sdi; struct sr_dev_inst *sdi;
@ -250,6 +250,7 @@ static void clear_instances(void)
g_slist_free(drvc->instances); g_slist_free(drvc->instances);
drvc->instances = NULL; drvc->instances = NULL;
return SR_OK;
} }
/* /*
@ -354,6 +355,15 @@ static GSList *hw_scan(GSList *options)
return devices; 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) static int hw_dev_open(struct sr_dev_inst *sdi)
{ {
struct dev_context *devc; struct dev_context *devc;
@ -687,6 +697,8 @@ SR_PRIV struct sr_dev_driver zeroplus_logic_cube_driver_info = {
.init = hw_init, .init = hw_init,
.cleanup = hw_cleanup, .cleanup = hw_cleanup,
.scan = hw_scan, .scan = hw_scan,
.dev_list = hw_dev_list,
.dev_clear = hw_cleanup,
.dev_open = hw_dev_open, .dev_open = hw_dev_open,
.dev_close = hw_dev_close, .dev_close = hw_dev_close,
.info_get = hw_info_get, .info_get = hw_info_get,

View File

@ -482,6 +482,8 @@ struct sr_dev_driver {
int (*init) (void); int (*init) (void);
int (*cleanup) (void); int (*cleanup) (void);
GSList *(*scan) (GSList *options); GSList *(*scan) (GSList *options);
GSList *(*dev_list) (void);
int (*dev_clear) (void);
/* Device-specific */ /* Device-specific */
int (*dev_open) (struct sr_dev_inst *sdi); int (*dev_open) (struct sr_dev_inst *sdi);

View File

@ -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 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, SR_API int sr_dev_config_set(const struct sr_dev_inst *sdi, int hwcap,
const void *value); 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 --------------------------------------------------------------*/ /*--- filter.c --------------------------------------------------------------*/