Each usbg_set_config_*() may fail so it should have a return value to notify user about reason of failure. To be consistent with rest of API usbg_create_config() should also return error code to notify user about reasons of failure instead of binary information (NULL or not). Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- examples/gadget-acm-ecm.c | 4 +- include/usbg/usbg.h | 23 ++++++---- src/usbg.c | 110 ++++++++++++++++++++++++++------------------- 3 files changed, 81 insertions(+), 56 deletions(-) diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c index 678514c..cda3808 100644 --- a/examples/gadget-acm-ecm.c +++ b/examples/gadget-acm-ecm.c @@ -87,8 +87,8 @@ int main(void) goto out2; } - c = usbg_create_config(g, "c.1", NULL /* use defaults */, &c_strs); - if (!c) { + usbg_ret = usbg_create_config(g, "c.1", NULL /* use defaults */, &c_strs, &c); + if (usbg_ret != USBG_SUCCESS) { fprintf(stderr, "Error creating config\n"); goto out2; } diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index 005f9eb..1fa9d22 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -466,10 +466,12 @@ extern int usbg_get_function_name(usbg_function *f, char *buf, size_t len); * @param name Name of configuration * @param c_attrs Configuration attributes to be set * @param c_strs Configuration strings to be set - * @return Pointer to configuration or NULL if it cannot be created + * @param c Pointer to be filled with pointer to configuration + * @note Given strings are assumed to be in US English + * @return 0 on success usbg_error if error occurred */ -extern usbg_config *usbg_create_config(usbg_gadget *g, char *name, - usbg_config_attrs *c_attrs, usbg_config_strs *c_strs); +extern int usbg_create_config(usbg_gadget *g, char *name, + usbg_config_attrs *c_attrs, usbg_config_strs *c_strs, usbg_config **c); /** * @brief Get config name length @@ -491,8 +493,9 @@ extern int usbg_get_config_name(usbg_config *c, char *buf, size_t len); * @brief Set the USB configuration attributes * @param c Pointer to configuration * @param c_attrs Configuration attributes + * @return 0 on success or usbg_error if error occurred. */ -extern void usbg_set_config_attrs(usbg_config *c, +extern int usbg_set_config_attrs(usbg_config *c, usbg_config_attrs *c_attrs); /** @@ -508,15 +511,17 @@ extern usbg_config_attrs *usbg_get_config_attrs(usbg_config *c, * @brief Set the configuration maximum power * @param c Pointer to config * @param bMaxPower Maximum power (in 2 mA units) + * @return 0 on success or usbg_error if error occurred. */ -extern void usbg_set_config_max_power(usbg_config *c, int bMaxPower); +extern int usbg_set_config_max_power(usbg_config *c, int bMaxPower); /** * @brief Set the configuration bitmap attributes * @param c Pointer to config * @param bmAttributes Configuration characteristics + * @return 0 on success or usbg_error if error occurred. */ -extern void usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes); +extern int usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes); /** * @brief Get the USB configuration strings @@ -533,8 +538,9 @@ extern usbg_config_strs *usbg_get_config_strs(usbg_config *c, int lang, * @param c Pointer to configuration * @param lang USB language ID * @param c_sttrs Configuration strings + * @return 0 on success, usbg_error on failure. */ -extern void usbg_set_config_strs(usbg_config *c, int lang, +extern int usbg_set_config_strs(usbg_config *c, int lang, usbg_config_strs *c_strs); /** @@ -542,8 +548,9 @@ extern void usbg_set_config_strs(usbg_config *c, int lang, * @param c Pointer to config * @param lang USB language ID * @param string Configuration description + * @return 0 on success, usbg_error on failure. */ -extern void usbg_set_config_string(usbg_config *c, int lang, char *string); +extern int usbg_set_config_string(usbg_config *c, int lang, char *string); /** * @brief Add a function to a configuration diff --git a/src/usbg.c b/src/usbg.c index 0b0a799..3c6c008 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -1215,53 +1215,58 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type, return ret; } -usbg_config *usbg_create_config(usbg_gadget *g, char *name, - usbg_config_attrs *c_attrs, usbg_config_strs *c_strs) +int usbg_create_config(usbg_gadget *g, char *name, + usbg_config_attrs *c_attrs, usbg_config_strs *c_strs, usbg_config **c) { char cpath[USBG_MAX_PATH_LENGTH]; - usbg_config *c; - int ret; + usbg_config *conf; + int ret = USBG_ERROR_INVALID_PARAM; - if (!g) - return NULL; + if (!g || !c) + return ret; /** * @todo Check for legal configuration name */ - c = usbg_get_config(g, name); - if (c) { + conf = usbg_get_config(g, name); + if (conf) { ERROR("duplicate configuration name\n"); - return NULL; + return USBG_ERROR_EXIST; } sprintf(cpath, "%s/%s/%s/%s", g->path, g->name, CONFIGS_DIR, name); - c = malloc(sizeof(usbg_config)); - if (!c) { - ERRORNO("allocating configuration\n"); - return NULL; - } + *c = malloc(sizeof(usbg_config)); + conf = *c; + if (conf) { + TAILQ_INIT(&conf->bindings); + strcpy(conf->name, name); + sprintf(conf->path, "%s/%s/%s", g->path, g->name, CONFIGS_DIR); - TAILQ_INIT(&c->bindings); - strcpy(c->name, name); - sprintf(c->path, "%s/%s/%s", g->path, g->name, CONFIGS_DIR); - - ret = mkdir(cpath, S_IRWXU|S_IRWXG|S_IRWXO); - if (ret < 0) { - ERRORNO("%s\n", cpath); - free(c); - return NULL; - } + ret = mkdir(cpath, S_IRWXU|S_IRWXG|S_IRWXO); + if (!ret) { + ret = USBG_SUCCESS; + if (c_attrs) + ret = usbg_set_config_attrs(conf, c_attrs); - if (c_attrs) - usbg_set_config_attrs(c, c_attrs); + if (ret == USBG_SUCCESS && c_strs) + ret = usbg_set_config_string(conf, LANG_US_ENG, + c_strs->configuration); - if (c_strs) - usbg_set_config_string(c, LANG_US_ENG, c_strs->configuration); + } else { + ret = usbg_translate_error(errno); + } - INSERT_TAILQ_STRING_ORDER(&g->configs, chead, name, c, cnode); + if (ret == USBG_SUCCESS) + INSERT_TAILQ_STRING_ORDER(&g->configs, chead, name, conf, cnode); + else + usbg_free_config(conf); + } else { + ERRORNO("allocating configuration\n"); + ret = USBG_ERROR_NO_MEM; + } - return c; + return ret; } size_t usbg_get_config_name_len(usbg_config *c) @@ -1296,13 +1301,18 @@ int usbg_get_function_name(usbg_function *f, char *buf, size_t len) return ret; } -void usbg_set_config_attrs(usbg_config *c, usbg_config_attrs *c_attrs) +int usbg_set_config_attrs(usbg_config *c, usbg_config_attrs *c_attrs) { - if (!c || !c_attrs) - return; + int ret = USBG_ERROR_INVALID_PARAM; - usbg_write_dec(c->path, c->name, "MaxPower", c_attrs->bMaxPower); - usbg_write_hex8(c->path, c->name, "bmAttributes", c_attrs->bmAttributes); + if (c && !c_attrs) { + ret = usbg_write_dec(c->path, c->name, "MaxPower", c_attrs->bMaxPower); + if (ret == USBG_SUCCESS) + ret = usbg_write_hex8(c->path, c->name, "bmAttributes", + c_attrs->bmAttributes); + } + + return ret; } usbg_config_attrs *usbg_get_config_attrs(usbg_config *c, @@ -1316,14 +1326,16 @@ usbg_config_attrs *usbg_get_config_attrs(usbg_config *c, return c_attrs; } -void usbg_set_config_max_power(usbg_config *c, int bMaxPower) +int usbg_set_config_max_power(usbg_config *c, int bMaxPower) { - usbg_write_dec(c->path, c->name, "MaxPower", bMaxPower); + return c ? usbg_write_dec(c->path, c->name, "MaxPower", bMaxPower) + : USBG_ERROR_INVALID_PARAM; } -void usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes) +int usbg_set_config_bm_attrs(usbg_config *c, int bmAttributes) { - usbg_write_hex8(c->path, c->name, "bmAttributes", bmAttributes); + return c ? usbg_write_hex8(c->path, c->name, "bmAttributes", bmAttributes) + : USBG_ERROR_INVALID_PARAM; } usbg_config_strs *usbg_get_config_strs(usbg_config *c, int lang, @@ -1337,21 +1349,27 @@ usbg_config_strs *usbg_get_config_strs(usbg_config *c, int lang, return c_strs; } -void usbg_set_config_strs(usbg_config *c, int lang, +int usbg_set_config_strs(usbg_config *c, int lang, usbg_config_strs *c_strs) { - usbg_set_config_string(c, lang, c_strs->configuration); + return usbg_set_config_string(c, lang, c_strs->configuration); } -void usbg_set_config_string(usbg_config *c, int lang, char *str) +int usbg_set_config_string(usbg_config *c, int lang, char *str) { - char path[USBG_MAX_PATH_LENGTH]; + int ret = USBG_ERROR_INVALID_PARAM; - sprintf(path, "%s/%s/%s/0x%x", c->path, c->name, STRINGS_DIR, lang); + if (c && str) { + char path[USBG_MAX_PATH_LENGTH]; - mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO); + sprintf(path, "%s/%s/%s/0x%x", c->path, c->name, STRINGS_DIR, lang); - usbg_write_string(path, "", "configuration", str); + ret = usbg_check_dir(path); + if (ret == USBG_SUCCESS) + ret = usbg_write_string(path, "", "configuration", str); + } + + return ret; } int usbg_add_config_function(usbg_config *c, char *name, usbg_function *f) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html