libusbgx: Add udc structure
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Thu, 18 Sep 2014 16:12:46 +0000 (18:12 +0200)
committerKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 22 Dec 2015 20:41:51 +0000 (21:41 +0100)
Add structure to store informations about available udcs
instead of using their names as a string.

Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
include/usbg/usbg.h
src/usbg.c

index 6adfe46..d066321 100644 (file)
@@ -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_attr
  * @brief Gadget attributes which can be set using
  * usbg_set_gadget_attr() function.
@@ -328,6 +334,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 */
 
 /**
index 7640dda..a686c85 100644 (file)
@@ -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
@@ -616,15 +626,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);
@@ -758,6 +783,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;
@@ -1280,6 +1325,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;
@@ -1288,11 +1363,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) {
+               ERROR("Unable to parse udcs");
+               goto out;
+       }
 
        ret = usbg_parse_gadgets(path, s);
        if (ret != USBG_SUCCESS)
                ERROR("unable to parse %s\n", path);
 
+out:
        return ret;
 }
 
@@ -1405,6 +1488,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;