/* USB gadget setup and teardown */
/**
- * @brief Get a list of UDC devices on the system
- * @param udc_list Pointer to pointer to dirent pointer
- * @return Number of UDC devices on success, usbg_error on failure
- */
-extern int usbg_get_udcs(struct dirent ***udc_list);
-
-/**
* @brief Enable a USB gadget device
* @param g Pointer to gadget
* @param udc Name of UDC to enable gadget
b = usbg_get_next_binding(b))
/**
+ * @def usbg_for_each_udc(b, c)
+ * Iterates over each udc
+ */
+#define usbg_for_each_udc(u, s) \
+ for (u = usbg_get_first_udc(s); \
+ u != NULL; \
+ u = usbg_get_next_udc(u))
+
+/**
* @brief Get first gadget in gadget list
* @param s State of library
* @return Pointer to gadget or NULL if list is empty.
extern usbg_binding *usbg_get_first_binding(usbg_config *c);
/**
+ * @brief Get first udc in udc list
+ * @param s State of library
+ * @return Pointer to udc or NULL if list is empty.
+ * @note UDCs are sorted in strings (name) order
+ */
+extern usbg_udc *usbg_get_first_udc(usbg_state *s);
+
+/**
* @brief Get the next gadget on a list.
* @param g Pointer to current gadget
* @return Next gadget or NULL if end of list.
*/
extern usbg_binding *usbg_get_next_binding(usbg_binding *b);
+/**
+ * @brief Get the next udc on a list.
+ * @param u Pointer to current udc
+ * @return Next udc or NULL if end of list.
+ */
+extern usbg_udc *usbg_get_next_udc(usbg_udc *u);
+
/* Import / Export API */
/**
return USBG_SUCCESS;
}
-int usbg_get_udcs(struct dirent ***udc_list)
-{
- int ret = USBG_ERROR_INVALID_PARAM;
-
- if (udc_list) {
- ret = scandir("/sys/class/udc", udc_list, file_select, alphasort);
- if (ret < 0)
- ret = usbg_translate_error(errno);
- }
-
- return ret;
-}
-
int usbg_enable_gadget(usbg_gadget *g, const char *udc)
{
- char gudc[USBG_MAX_STR_LENGTH];
- struct dirent **udc_list;
- int i;
+ usbg_udc *sudc;
int ret = USBG_ERROR_INVALID_PARAM;
if (!g)
return ret;
if (!udc) {
- ret = usbg_get_udcs(&udc_list);
- if (ret >= 0) {
- /* Look for default one - first in string order */
- strcpy(gudc, udc_list[0]->d_name);
- udc = gudc;
-
- /** Free the memory */
- for (i = 0; i < ret; ++i)
- free(udc_list[i]);
- free(udc_list);
- } else {
+ sudc = usbg_get_first_udc(g->parent);
+ if (sudc)
+ udc = sudc->name;
+ else
return ret;
- }
}
ret = usbg_write_string(g->path, g->name, "UDC", udc);
- if (ret == USBG_SUCCESS)
- strcpy(g->udc, udc);
+ if (ret == USBG_SUCCESS) {
+ strncpy(g->udc, udc, USBG_MAX_STR_LENGTH);
+ g->udc[USBG_MAX_STR_LENGTH - 1] = '\0';
+ }
return ret;
}
return c ? TAILQ_FIRST(&c->bindings) : NULL;
}
+usbg_udc *usbg_get_first_udc(usbg_state *s)
+{
+ return s ? TAILQ_FIRST(&s->udcs) : NULL;
+}
+
usbg_gadget *usbg_get_next_gadget(usbg_gadget *g)
{
return g ? TAILQ_NEXT(g, gnode) : NULL;
return b ? TAILQ_NEXT(b, bnode) : NULL;
}
+usbg_udc *usbg_get_next_udc(usbg_udc *u)
+{
+ return u ? TAILQ_NEXT(u, unode) : NULL;
+}
+
#define USBG_NAME_TAG "name"
#define USBG_ATTRS_TAG "attrs"
#define USBG_STRINGS_TAG "strings"