From 0cd967b99bbd4c013ba7a87cb4e72069cdbdc7e3 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Tue, 23 Sep 2014 11:56:11 +0200 Subject: [PATCH] libusbgx: Rework API to use usbg_udc structure 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 --- 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 31df2e9..3fda9e2 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 c8ba2b2..0392223 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; -- 2.7.4