Using string as udc identifier provides a lot
of troubles. To be more consistent with rest of
API rework it to start using usbg_udc structure
instead of using char *.

Signed-off-by: Krzysztof Opasiak <k.opas...@samsung.com>
---
 examples/gadget-vid-pid-remove.c |   12 ++---
 examples/show-gadgets.c          |   15 ++++--
 include/usbg/usbg.h              |   29 +++++++++---
 src/usbg.c                       |   96 ++++++++++++++++++++++++--------------
 4 files changed, 98 insertions(+), 54 deletions(-)

diff --git a/examples/gadget-vid-pid-remove.c b/examples/gadget-vid-pid-remove.c
index 25e763f..c3f9c9b 100644
--- a/examples/gadget-vid-pid-remove.c
+++ b/examples/gadget-vid-pid-remove.c
@@ -31,19 +31,13 @@
 int remove_gadget(usbg_gadget *g)
 {
        int usbg_ret;
-       char udc[USBG_MAX_STR_LENGTH];
+       usbg_udc *u;
 
        /* Check if gadget is enabled */
-       usbg_ret = usbg_get_gadget_udc(g, udc, USBG_MAX_STR_LENGTH);
-       if (usbg_ret != USBG_SUCCESS) {
-               fprintf(stderr, "Error on USB get gadget udc\n");
-               fprintf(stderr, "Error: %s : %s\n", usbg_error_name(usbg_ret),
-                               usbg_strerror(usbg_ret));
-               goto out;
-       }
+       u = usbg_get_gadget_udc(g);
 
        /* If gadget is enable we have to disable it first */
-       if (udc[0] != '\0') {
+       if (u) {
                usbg_ret = usbg_disable_gadget(g);
                if (usbg_ret != USBG_SUCCESS) {
                        fprintf(stderr, "Error on USB disable gadget udc\n");
diff --git a/examples/show-gadgets.c b/examples/show-gadgets.c
index 823188f..e5da2ce 100644
--- a/examples/show-gadgets.c
+++ b/examples/show-gadgets.c
@@ -29,8 +29,8 @@
 
 void show_gadget(usbg_gadget *g)
 {
-       char buf[USBG_MAX_STR_LENGTH];
-       const char *name;
+       const char *name, *udc;
+       usbg_udc *u;
        int usbg_ret;
        usbg_gadget_attrs g_attrs;
        usbg_gadget_strs g_strs;
@@ -51,8 +51,15 @@ void show_gadget(usbg_gadget *g)
        fprintf(stdout, "ID %04x:%04x '%s'\n",
                        g_attrs.idVendor, g_attrs.idProduct, name);
 
-       usbg_get_gadget_udc(g, buf, USBG_MAX_STR_LENGTH);
-       fprintf(stdout, "  UDC\t\t\t%s\n", buf);
+       u = usbg_get_gadget_udc(g);
+       if (u)
+               /* gadget is enabled */
+               udc = usbg_get_udc_name(u);
+       else
+               /* gadget is disabled */
+               udc = "\0";
+
+       fprintf(stdout, "  UDC\t\t\t%s\n", udc);
 
        fprintf(stdout, "  bDeviceClass\t\t0x%02x\n", g_attrs.bDeviceClass);
        fprintf(stdout, "  bDeviceSubClass\t0x%02x\n", g_attrs.bDeviceSubClass);
diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 86a49e8..f5d0098 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -838,10 +838,11 @@ extern int usbg_cpy_binding_name(usbg_binding *b, char 
*buf, size_t len);
 /**
  * @brief Enable a USB gadget device
  * @param g Pointer to gadget
- * @param udc Name of UDC to enable gadget
+ * @param udc where gadget should be assigned.
+ *  If NULL, default one (first) is used.
  * @return 0 on success or usbg_error if error occurred.
  */
-extern int usbg_enable_gadget(usbg_gadget *g, const char *udc);
+extern int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc);
 
 /**
  * @brief Disable a USB gadget device
@@ -851,6 +852,16 @@ extern int usbg_enable_gadget(usbg_gadget *g, const char 
*udc);
 extern int usbg_disable_gadget(usbg_gadget *g);
 
 /**
+ * @brief Get name of udc
+ * @param u Pointer to udc
+ * @return UDC name or NULL if error occurred.
+ * @warning Returned buffer should not be edited!
+ * Returned string is valid as long as passed usbg_state is valid.
+ * For example UDC name is valid until usbg_cleanup().
+ */
+extern const char *usbg_get_udc_name(usbg_udc *u);
+
+/**
  * @brief Get gadget name length
  * @param g Gadget which name length should be returned
  * @return Length of name string or usbg_error if error occurred.
@@ -859,14 +870,20 @@ extern int usbg_disable_gadget(usbg_gadget *g);
 extern size_t usbg_get_gadget_udc_len(usbg_gadget *g);
 
 /**
- * @brief Get name of udc to which gadget is binded
- * @param g Pointer to gadget
+ * @brief Copy name of udc
+ * @param u Pointer to udc
  * @param buf Buffer where udc name should be copied
  * @param len Length of given buffer
  * @return 0 on success or usbg_error if error occurred.
- * @note If gadget isn't enabled on any udc returned string is empty.
  */
-extern int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len);
+extern int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len);
+
+/**
+ * @brief Get udc to which gadget is binded
+ * @param g Pointer to gadget
+ * @return Pointer to UDC or NULL if gadget is not enabled
+ */
+extern usbg_udc *usbg_get_gadget_udc(usbg_gadget *g);
 
 /*
  * USB function-specific attribute configuration
diff --git a/src/usbg.c b/src/usbg.c
index 8c3e2fe..3a8e656 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -50,13 +50,13 @@ struct usbg_gadget
 {
        char *name;
        char *path;
-       char udc[USBG_MAX_STR_LENGTH];
 
        TAILQ_ENTRY(usbg_gadget) gnode;
        TAILQ_HEAD(chead, usbg_config) configs;
        TAILQ_HEAD(fhead, usbg_function) functions;
        usbg_state *parent;
        config_t *last_failed_import;
+       usbg_udc *udc;
 };
 
 struct usbg_config
@@ -672,6 +672,7 @@ static usbg_gadget *usbg_allocate_gadget(const char *path, 
const char *name,
                g->name = strdup(name);
                g->path = strdup(path);
                g->parent = parent;
+               g->udc = NULL;
 
                if (!(g->name) || !(g->path)) {
                        free(g->name);
@@ -1275,12 +1276,17 @@ out:
 static inline int usbg_parse_gadget(usbg_gadget *g)
 {
        int ret;
+       char buf[USBG_MAX_STR_LENGTH];
 
        /* UDC bound to, if any */
-       ret = usbg_read_string(g->path, g->name, "UDC", g->udc);
+       ret = usbg_read_string(g->path, g->name, "UDC", buf);
        if (ret != USBG_SUCCESS)
                goto out;
 
+       g->udc = usbg_get_udc(g->parent, buf);
+       if (g->udc)
+               g->udc->gadget = g;
+
        ret = usbg_parse_functions(g->path, g);
        if (ret != USBG_SUCCESS)
                goto out;
@@ -1725,7 +1731,9 @@ static int usbg_create_empty_gadget(usbg_state *s, const 
char *name,
                                    usbg_gadget **g)
 {
        char gpath[USBG_MAX_PATH_LENGTH];
+       char buf[USBG_MAX_STR_LENGTH];
        int nmb;
+       usbg_gadget *gad;
        int ret = USBG_SUCCESS;
 
        nmb = snprintf(gpath, sizeof(gpath), "%s/%s", s->path, name);
@@ -1735,26 +1743,32 @@ static int usbg_create_empty_gadget(usbg_state *s, 
const char *name,
        }
 
        *g = usbg_allocate_gadget(s->path, name, s);
-       if (*g) {
-               usbg_gadget *gad = *g; /* alias only */
-
-               ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO);
-               if (ret == 0) {
-                       /* Should be empty but read the default */
-                       ret = usbg_read_string(gad->path, gad->name, "UDC",
-                                gad->udc);
-                       if (ret != USBG_SUCCESS)
-                               rmdir(gpath);
-               } else {
-                       ret = usbg_translate_error(errno);
-               }
+       if (!*g) {
+               ret = USBG_ERROR_NO_MEM;
+               goto out;
+       }
+
+       gad = *g; /* alias only */
 
+       ret = mkdir(gpath, S_IRWXU|S_IRWXG|S_IRWXO);
+       if (ret == 0) {
+               /* Should be empty but read the default */
+               ret = usbg_read_string(gad->path, gad->name,
+                                      "UDC", buf);
                if (ret != USBG_SUCCESS) {
-                       usbg_free_gadget(*g);
-                       *g = NULL;
+                       rmdir(gpath);
+               } else {
+                       gad->udc = usbg_get_udc(s, buf);
+                       if (gad->udc)
+                               gad->udc->gadget = gad;
                }
        } else {
-               ret = USBG_ERROR_NO_MEM;
+               ret = usbg_translate_error(errno);
+       }
+
+       if (ret != USBG_SUCCESS) {
+               usbg_free_gadget(*g);
+               *g = NULL;
        }
 
 out:
@@ -1858,18 +1872,23 @@ int usbg_cpy_gadget_name(usbg_gadget *g, char *buf, 
size_t len)
        return USBG_SUCCESS;
 }
 
-size_t usbg_get_gadget_udc_len(usbg_gadget *g)
+const char *usbg_get_udc_name(usbg_udc *u)
 {
-       return g ? strlen(g->udc) : USBG_ERROR_INVALID_PARAM;
+       return u ? u->name : NULL;
 }
 
-int usbg_get_gadget_udc(usbg_gadget *g, char *buf, size_t len)
+size_t usbg_get_udc_name_len(usbg_udc *u)
 {
-       if (!g || !buf || len == 0)
+       return u ? strlen(u->name) : USBG_ERROR_INVALID_PARAM;
+}
+
+int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len)
+{
+       if (!u || !buf || len == 0)
                return USBG_ERROR_INVALID_PARAM;
 
        buf[--len] = '\0';
-       strncpy(buf, g->udc, len);
+       strncpy(buf, u->name, len);
 
        return USBG_SUCCESS;
 }
@@ -1910,6 +1929,11 @@ out:
        return ret;
 }
 
+usbg_udc *usbg_get_gadget_udc(usbg_gadget *g)
+{
+       return g ? g->udc : NULL;
+}
+
 int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs)
 {
        int ret;
@@ -2472,27 +2496,24 @@ int usbg_cpy_binding_name(usbg_binding *b, char *buf, 
size_t len)
        return USBG_SUCCESS;
 }
 
-int usbg_enable_gadget(usbg_gadget *g, const char *udc)
+int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc)
 {
-       usbg_udc *sudc;
        int ret = USBG_ERROR_INVALID_PARAM;
 
        if (!g)
                return ret;
 
        if (!udc) {
-               sudc = usbg_get_first_udc(g->parent);
-               if (sudc)
-                       udc = sudc->name;
-               else
+               udc = usbg_get_first_udc(g->parent);
+               if (!udc)
                        return ret;
        }
 
-       ret = usbg_write_string(g->path, g->name, "UDC", udc);
+       ret = usbg_write_string(g->path, g->name, "UDC", udc->name);
 
        if (ret == USBG_SUCCESS) {
-               strncpy(g->udc, udc, USBG_MAX_STR_LENGTH);
-               g->udc[USBG_MAX_STR_LENGTH - 1] = '\0';
+               g->udc = udc;
+               udc->gadget = g;
        }
 
        return ret;
@@ -2502,9 +2523,14 @@ int usbg_disable_gadget(usbg_gadget *g)
 {
        int ret = USBG_ERROR_INVALID_PARAM;
 
-       if (g) {
-               strcpy(g->udc, "");
-               ret = usbg_write_string(g->path, g->name, "UDC", "\n");
+       if (!g)
+               return ret;
+
+       ret = usbg_write_string(g->path, g->name, "UDC", "\n");
+       if (ret == USBG_SUCCESS) {
+               if (g->udc)
+                       g->udc->gadget = NULL;
+               g->udc = NULL;
        }
 
        return ret;
-- 
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