[PATCH v2 3/6] libusbg: Rework API to use usbg_udc structure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.opasiak@xxxxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux