[PATCH 4/9] libusbg: Add udc structure

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

 



Add structure to store informations about available udcs
instead of using their names as a string.

Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
---
 include/usbg/usbg.h |   14 ++++++++
 src/usbg.c          |   94 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+)

diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index 3f5d561..c0e19d0 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -61,6 +61,7 @@ struct usbg_gadget;
 struct usbg_config;
 struct usbg_function;
 struct usbg_binding;
+struct usbg_udc;
 
 /**
  * @brief State of the gadget devices in the system
@@ -88,6 +89,11 @@ typedef struct usbg_function usbg_function;
 typedef struct usbg_binding usbg_binding;
 
 /**
+ * @brief USB device controler
+ */
+typedef struct usbg_udc usbg_udc;
+
+/**
  * @typedef usbg_gadget_attrs
  * @brief USB gadget device attributes
  */
@@ -312,6 +318,14 @@ extern usbg_function *usbg_get_function(usbg_gadget *g,
  */
 extern usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label);
 
+/**
+ * @brief Get a udc by name
+ * @param s Pointer to state
+ * @param name Name of the udc
+ * @return Pointer to udc or NULL if a matching udc isn't found
+ */
+extern usbg_udc *usbg_get_udc(usbg_state *s, const char *name);
+
 /* USB gadget/config/function/binding removal */
 
 /**
diff --git a/src/usbg.c b/src/usbg.c
index 5f910f0..5f44cbd 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -42,6 +42,7 @@ struct usbg_state
 	char *path;
 
 	TAILQ_HEAD(ghead, usbg_gadget) gadgets;
+	TAILQ_HEAD(uhead, usbg_udc) udcs;
 	config_t *last_failed_import;
 };
 
@@ -93,6 +94,15 @@ struct usbg_binding
 	char *path;
 };
 
+struct usbg_udc
+{
+	TAILQ_ENTRY(usbg_udc) unode;
+	usbg_state *parent;
+	usbg_gadget *gadget;
+
+	char *name;
+};
+
 /**
  * @var function_names
  * @brief Name strings for supported USB function types
@@ -582,15 +592,30 @@ static void usbg_free_gadget(usbg_gadget *g)
 	free(g);
 }
 
+static void usbg_free_udc(usbg_udc *u)
+{
+	free(u->name);
+	free(u);
+}
+
 static void usbg_free_state(usbg_state *s)
 {
 	usbg_gadget *g;
+	usbg_udc *u;
+
 	while (!TAILQ_EMPTY(&s->gadgets)) {
 		g = TAILQ_FIRST(&s->gadgets);
 		TAILQ_REMOVE(&s->gadgets, g, gnode);
 		usbg_free_gadget(g);
 	}
 
+
+	while (!TAILQ_EMPTY(&s->udcs)) {
+		u = TAILQ_FIRST(&s->udcs);
+		TAILQ_REMOVE(&s->udcs, u, unode);
+		usbg_free_udc(u);
+	}
+
 	if (s->last_failed_import) {
 		config_destroy(s->last_failed_import);
 		free(s->last_failed_import);
@@ -724,6 +749,26 @@ static usbg_binding *usbg_allocate_binding(const char *path, const char *name,
 	return b;
 }
 
+static usbg_udc *usbg_allocate_udc(usbg_state *parent, const char *name)
+{
+	usbg_udc *u;
+
+	u = malloc(sizeof(*u));
+	if (!u)
+		goto out;
+
+	u->gadget = NULL;
+	u->parent = parent;
+	u->name = strdup(name);
+	if (!u->name) {
+		free(u);
+		u = NULL;
+	}
+
+ out:
+	return u;
+}
+
 static int ubsg_rm_file(const char *path, const char *name)
 {
 	int ret = USBG_SUCCESS;
@@ -1246,6 +1291,36 @@ static int usbg_parse_gadgets(const char *path, usbg_state *s)
 	return ret;
 }
 
+static int usbg_parse_udcs(usbg_state *s)
+{
+	usbg_udc *u;
+	int n, i;
+	int ret = USBG_SUCCESS;
+	struct dirent **dent;
+
+	n = scandir("/sys/class/udc", &dent, file_select, alphasort);
+	if (n < 0) {
+		ret = usbg_translate_error(errno);
+		goto out;
+	}
+
+	for (i = 0; i < n; ++i) {
+		if (ret == USBG_SUCCESS) {
+			u = usbg_allocate_udc(s, dent[i]->d_name);
+			if (u)
+				TAILQ_INSERT_TAIL(&s->udcs, u, unode);
+			else
+				ret = USBG_ERROR_NO_MEM;
+		}
+
+		free(dent[i]);
+	}
+	free(dent);
+
+out:
+	return ret;
+}
+
 static int usbg_init_state(char *path, usbg_state *s)
 {
 	int ret = USBG_SUCCESS;
@@ -1254,11 +1329,19 @@ static int usbg_init_state(char *path, usbg_state *s)
 	s->path = path;
 	s->last_failed_import = NULL;
 	TAILQ_INIT(&s->gadgets);
+	TAILQ_INIT(&s->udcs);
+
+	ret = usbg_parse_udcs(s);
+	if (ret != USBG_SUCCESS) {
+		ERRORNO("Unable to parse udcs");
+		goto out;
+	}
 
 	ret = usbg_parse_gadgets(path, s);
 	if (ret != USBG_SUCCESS)
 		ERRORNO("unable to parse %s\n", path);
 
+out:
 	return ret;
 }
 
@@ -1373,6 +1456,17 @@ usbg_config *usbg_get_config(usbg_gadget *g, int id, const char *label)
 	return c;
 }
 
+usbg_udc *usbg_get_udc(usbg_state *s, const char *name)
+{
+	usbg_udc *u;
+
+	TAILQ_FOREACH(u, &s->udcs, unode)
+		if (!strcmp(u->name, name))
+			return u;
+
+	return NULL;
+}
+
 usbg_binding *usbg_get_binding(usbg_config *c, const char *name)
 {
 	usbg_binding *b;
-- 
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