]> sigrok.org Git - libsigrok.git/blobdiff - src/hwdriver.c
drivers: Add and use STD_CONFIG_LIST().
[libsigrok.git] / src / hwdriver.c
index 3e6b00126488ef58dd562cef0f7d12f124ce742b..96b6cfac0d48b4d24c67c61e88cc8074599f5fe9 100644 (file)
@@ -853,18 +853,19 @@ SR_API int sr_config_commit(const struct sr_dev_inst *sdi)
  * List all possible values for a configuration key.
  *
  * @param[in] driver The sr_dev_driver struct to query. Must not be NULL.
- * @param[in] sdi (optional) If the key is specific to a device, this must
- *            contain a pointer to the struct sr_dev_inst to be checked.
+ * @param[in] sdi (optional) If the key is specific to a device instance, this
+ *            must contain a pointer to the struct sr_dev_inst to be checked.
  *            Otherwise it must be NULL. If sdi is != NULL, sdi->priv must
  *            also be != NULL.
- * @param[in] cg The channel group on the device for which to list the
- *                    values, or NULL.
+ * @param[in] cg The channel group on the device instance for which to list
+ *            the values, or NULL. If this device instance doesn't
+ *            have channel groups, this must not be != NULL.
  * @param[in] key The configuration key (SR_CONF_*).
  * @param[in,out] data A pointer to a GVariant where the list will be stored.
- *             The caller is given ownership of the GVariant and must thus
- *             unref the GVariant after use. However if this function
- *             returns an error code, the field should be considered
- *             unused, and should not be unreferenced.
+ *                The caller is given ownership of the GVariant and must thus
+ *                unref the GVariant after use. However if this function
+ *                returns an error code, the field should be considered
+ *                unused, and should not be unreferenced.
  *
  * @retval SR_OK Success.
  * @retval SR_ERR Error.
@@ -883,21 +884,50 @@ SR_API int sr_config_list(const struct sr_dev_driver *driver,
 
        if (!driver || !data)
                return SR_ERR;
-       else if (!driver->config_list)
+
+       if (!driver->config_list)
                return SR_ERR_ARG;
-       else if (key != SR_CONF_SCAN_OPTIONS && key != SR_CONF_DEVICE_OPTIONS) {
+
+       if (key != SR_CONF_SCAN_OPTIONS && key != SR_CONF_DEVICE_OPTIONS) {
                if (check_key(driver, sdi, cg, key, SR_CONF_LIST, NULL) != SR_OK)
                        return SR_ERR_ARG;
        }
+
        if (sdi && !sdi->priv) {
                sr_err("Can't list config (sdi != NULL, sdi->priv == NULL).");
                return SR_ERR;
        }
+
+       if (key != SR_CONF_SCAN_OPTIONS && key != SR_CONF_DEVICE_OPTIONS && !sdi) {
+               sr_err("Config keys other than SR_CONF_SCAN_OPTIONS and "
+                      "SR_CONF_DEVICE_OPTIONS always need an sdi.");
+               return SR_ERR_ARG;
+       }
+
+       if (cg && sdi && !sdi->channel_groups) {
+               sr_err("Can't list config for channel group, there are none.");
+               return SR_ERR_ARG;
+       }
+
+       if (cg && sdi && !g_slist_find(sdi->channel_groups, cg)) {
+               sr_err("If a channel group is specified, it must be a valid one.");
+               return SR_ERR_ARG;
+       }
+
+       if (cg && !sdi) {
+               sr_err("Need sdi when a channel group is specified.");
+               return SR_ERR_ARG;
+       }
+
        if ((ret = driver->config_list(key, data, sdi, cg)) == SR_OK) {
                log_key(sdi, cg, key, SR_CONF_LIST, *data);
                g_variant_ref_sink(*data);
        }
 
+       if (ret == SR_ERR_CHANNEL_GROUP)
+               sr_err("%s: No channel group specified.",
+                       (sdi) ? sdi->driver->name : "unknown");
+
        return ret;
 }