Each usbg_set_*() 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_function()
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.opas...@samsung.com>
---
 examples/gadget-acm-ecm.c |   12 ++--
 include/usbg/usbg.h       |   20 ++++---
 src/usbg.c                |  140 ++++++++++++++++++++++++++++-----------------
 3 files changed, 108 insertions(+), 64 deletions(-)

diff --git a/examples/gadget-acm-ecm.c b/examples/gadget-acm-ecm.c
index b1131b4..678514c 100644
--- a/examples/gadget-acm-ecm.c
+++ b/examples/gadget-acm-ecm.c
@@ -69,20 +69,20 @@ int main(void)
                goto out2;
        }
 
-       f_acm0 = usbg_create_function(g, F_ACM, "usb0", NULL);
-       if (!f_acm0) {
+       usbg_ret = usbg_create_function(g, F_ACM, "usb0", NULL, &f_acm0);
+       if (usbg_ret != USBG_SUCCESS) {
                fprintf(stderr, "Error creating acm0 function\n");
                goto out2;
        }
 
-       f_acm1 = usbg_create_function(g, F_ACM, "usb1", NULL);
-       if (!f_acm1) {
+       usbg_ret = usbg_create_function(g, F_ACM, "usb1", NULL, &f_acm1);
+       if (usbg_ret != USBG_SUCCESS) {
                fprintf(stderr, "Error creating acm1 function\n");
                goto out2;
        }
 
-       f_ecm = usbg_create_function(g, F_ECM, "usb0", NULL);
-       if (!f_ecm) {
+       usbg_ret = usbg_create_function(g, F_ECM, "usb0", NULL, &f_acm1);
+       if (usbg_ret != USBG_SUCCESS) {
                fprintf(stderr, "Error creating ecm function\n");
                goto out2;
        }
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 17084bb..005f9eb 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -435,10 +435,12 @@ extern int usbg_set_gadget_product(usbg_gadget *g, int 
lang, char *prd);
  * @param type Type of function
  * @param instance Function instance name
  * @param f_attrs Function attributes to be set. If NULL setting is omitted.
- * @return Pointer to function or NULL if it cannot be created
+ * @param f Pointer to be filled with pointer to function
+ * @note Given strings are assumed to be in US English
+ * @return 0 on success usbg_error if error occurred
  */
-extern usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type 
type,
-               char *instance, usbg_function_attrs *f_attrs);
+extern int usbg_create_function(usbg_gadget *g, usbg_function_type type,
+               char *instance, usbg_function_attrs *f_attrs, usbg_function 
**f);
 
 /**
  * @brief Get function name length
@@ -640,29 +642,33 @@ extern usbg_function_attrs 
*usbg_get_function_attrs(usbg_function *f,
  * @brief Set attributes of given function
  * @param f Pointer to function
  * @param f_attrs Attributes to be set
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs 
*f_attrs);
+extern int usbg_set_function_attrs(usbg_function *f, usbg_function_attrs 
*f_attrs);
 
 /**
  * @brief Set USB function network device address
  * @param f Pointer to function
  * @param addr Pointer to Ethernet address
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr);
+extern int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *addr);
 
 /**
  * @brief Set USB function network host address
  * @param f Pointer to function
  * @param addr Pointer to Ethernet address
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr);
+extern int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *addr);
 
 /**
  * @brief Set USB function network qmult
  * @param f Pointer to function
  * @param qmult Queue length multiplier
+ * @return 0 on success, usbg_error if error occurred
  */
-extern void usbg_set_net_qmult(usbg_function *f, int qmult);
+extern int usbg_set_net_qmult(usbg_function *f, int qmult);
 
 /**
  * @def usbg_for_each_gadget(g, s)
diff --git a/src/usbg.c b/src/usbg.c
index 5a4202c..08cd397 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -1162,52 +1162,58 @@ int usbg_set_gadget_product(usbg_gadget *g, int lang, 
char *prd)
        return ret;
 }
 
-usbg_function *usbg_create_function(usbg_gadget *g, usbg_function_type type,
-               char *instance, usbg_function_attrs *f_attrs)
+int usbg_create_function(usbg_gadget *g, usbg_function_type type,
+               char *instance, usbg_function_attrs *f_attrs, usbg_function **f)
 {
        char fpath[USBG_MAX_PATH_LENGTH];
        char name[USBG_MAX_STR_LENGTH];
-       usbg_function *f;
-       int ret;
+       usbg_function *func;
+       int ret = USBG_ERROR_INVALID_PARAM;
 
-       if (!g)
-               return NULL;
+       if (!g || !f)
+               return ret;
 
        /**
         * @todo Check for legal function type
         */
        sprintf(name, "%s.%s", function_names[type], instance);
-       f = usbg_get_function(g, name);
-       if (f) {
+       func = usbg_get_function(g, name);
+       if (func) {
                ERROR("duplicate function name\n");
-               return NULL;
+               return USBG_ERROR_EXIST;
        }
 
        sprintf(fpath, "%s/%s/%s/%s", g->path, g->name, FUNCTIONS_DIR, name);
 
-       f = malloc(sizeof(usbg_function));
-       if (!f) {
-               ERRORNO("allocating function\n");
-               return NULL;
-       }
-
-       strcpy(f->name, name);
-       sprintf(f->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR);
-       f->type = type;
+       *f = malloc(sizeof(usbg_function));
+       func = *f;
+       if (func) {
+               strcpy(func->name, name);
+               sprintf(func->path, "%s/%s/%s", g->path, g->name, 
FUNCTIONS_DIR);
+               func->type = type;
 
-       ret = mkdir(fpath, S_IRWXU|S_IRWXG|S_IRWXO);
-       if (ret < 0) {
-               ERRORNO("%s\n", fpath);
-               free(f);
-               return NULL;
-       }
+               ret = mkdir(fpath, S_IRWXU | S_IRWXG | S_IRWXO);
 
-       if (f_attrs)
-               usbg_set_function_attrs(f, f_attrs);
+               if (!ret) {
+                       /* Success */
+                       ret = USBG_SUCCESS;
+                       if (f_attrs)
+                               ret = usbg_set_function_attrs(func, f_attrs);
+               } else {
+                       ret = usbg_translate_error(errno);
+               }
 
-       INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, f, fnode);
+               if (ret == USBG_SUCCESS)
+                       INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name,
+                               func, fnode);
+               else
+                       usbg_free_function(func);
+       } else {
+               ERRORNO("allocating function\n");
+               ret = USBG_ERROR_NO_MEM;
+       }
 
-       return f;
+       return ret;
 }
 
 usbg_config *usbg_create_config(usbg_gadget *g, char *name,
@@ -1469,61 +1475,93 @@ usbg_function_attrs 
*usbg_get_function_attrs(usbg_function *f,
        return f_attrs;
 }
 
-void usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
+int usbg_set_function_net_attrs(usbg_function *f, usbg_f_net_attrs *attrs)
 {
+       int ret = USBG_SUCCESS;
        char *addr;
 
+       addr = ether_ntoa(&attrs->dev_addr);
+       ret = usbg_write_string(f->path, f->name, "dev_addr", addr);
+       if (ret != USBG_SUCCESS)
+               goto out;
+
+       addr = ether_ntoa(&attrs->host_addr);
+       ret = usbg_write_string(f->path, f->name, "host_addr", addr);
+       if (ret != USBG_SUCCESS)
+               goto out;
+
+       ret = usbg_write_string(f->path, f->name, "ifname", attrs->ifname);
+       if (ret != USBG_SUCCESS)
+               goto out;
+
+       ret = usbg_write_dec(f->path, f->name, "qmult", attrs->qmult);
+
+out:
+       return ret;
+}
+
+int  usbg_set_function_attrs(usbg_function *f, usbg_function_attrs *f_attrs)
+{
+       int ret = USBG_ERROR_INVALID_PARAM;
+
        if (!f || !f_attrs)
-               return;
+               return USBG_ERROR_INVALID_PARAM;
 
        switch (f->type) {
        case F_SERIAL:
        case F_ACM:
        case F_OBEX:
-               usbg_write_dec(f->path, f->name, "port_num", 
f_attrs->serial.port_num);
+               ret = usbg_write_dec(f->path, f->name, "port_num", 
f_attrs->serial.port_num);
                break;
        case F_ECM:
        case F_SUBSET:
        case F_NCM:
        case F_EEM:
        case F_RNDIS:
-               addr = ether_ntoa(&f_attrs->net.dev_addr);
-               usbg_write_string(f->path, f->name, "dev_addr", addr);
-
-               addr = ether_ntoa(&f_attrs->net.host_addr);
-               usbg_write_string(f->path, f->name, "host_addr", addr);
-
-               usbg_write_string(f->path, f->name, "ifname", 
f_attrs->net.ifname);
-
-               usbg_write_dec(f->path, f->name, "qmult", f_attrs->net.qmult);
+               ret = usbg_set_function_net_attrs(f, &f_attrs->net);
                break;
        case F_PHONET:
-               usbg_write_string(f->path, f->name, "ifname", 
f_attrs->phonet.ifname);
+               ret = usbg_write_string(f->path, f->name, "ifname", 
f_attrs->phonet.ifname);
                break;
        default:
                ERROR("Unsupported function type\n");
        }
+
+       return ret;
 }
 
-void usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr)
+int usbg_set_net_dev_addr(usbg_function *f, struct ether_addr *dev_addr)
 {
-       char *str_addr;
+       int ret = USBG_SUCCESS;
+
+       if (f && dev_addr) {
+               char *str_addr = ether_ntoa(dev_addr);
+               ret = usbg_write_string(f->path, f->name, "dev_addr", str_addr);
+       } else {
+               ret = USBG_ERROR_INVALID_PARAM;
+       }
 
-       str_addr = ether_ntoa(dev_addr);
-       usbg_write_string(f->path, f->name, "dev_addr", str_addr);
+       return ret;
 }
 
-void usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr)
+int usbg_set_net_host_addr(usbg_function *f, struct ether_addr *host_addr)
 {
-       char *str_addr;
+       int ret = USBG_SUCCESS;
 
-       str_addr = ether_ntoa(host_addr);
-       usbg_write_string(f->path, f->name, "host_addr", str_addr);
+       if (f && host_addr) {
+               char *str_addr = ether_ntoa(host_addr);
+               ret = usbg_write_string(f->path, f->name, "host_addr", 
str_addr);
+       } else {
+               ret = USBG_ERROR_INVALID_PARAM;
+       }
+
+       return ret;
 }
 
-void usbg_set_net_qmult(usbg_function *f, int qmult)
+int usbg_set_net_qmult(usbg_function *f, int qmult)
 {
-       usbg_write_dec(f->path, f->name, "qmult", qmult);
+       return f ? usbg_write_dec(f->path, f->name, "qmult", qmult)
+                       : USBG_ERROR_INVALID_PARAM;
 }
 
 usbg_gadget *usbg_get_first_gadget(usbg_state *s)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to