Enabling and disabling gadget may fail due to many reasons so those functions should notify user about it. Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- include/usbg/usbg.h | 10 +++++--- src/usbg.c | 67 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h index 1fa9d22..3ad98b6 100644 --- a/include/usbg/usbg.h +++ b/include/usbg/usbg.h @@ -187,6 +187,8 @@ typedef enum { USBG_ERROR_NOT_FOUND = -4, USBG_ERROR_IO = -5, USBG_ERROR_EXIST = -6, + USBG_ERROR_NO_DEV = -7, + USBG_ERROR_BUSY = -8, USBG_ERROR_OTHER_ERROR = -99 } usbg_error; @@ -589,7 +591,7 @@ extern int usbg_get_binding_name(usbg_binding *b, char *buf, size_t len); /** * @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, -1 on failure + * @return Number of UDC devices on success, usbg_error on failure */ extern int usbg_get_udcs(struct dirent ***udc_list); @@ -597,14 +599,16 @@ 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 + * @return 0 on success or usbg_error if error occurred. */ -extern void usbg_enable_gadget(usbg_gadget *g, char *udc); +extern int usbg_enable_gadget(usbg_gadget *g, char *udc); /** * @brief Disable a USB gadget device * @param g Pointer to gadget + * @return 0 on success or usbg_error if error occurred. */ -extern void usbg_disable_gadget(usbg_gadget *g); +extern int usbg_disable_gadget(usbg_gadget *g); /** * @brief Get gadget name length diff --git a/src/usbg.c b/src/usbg.c index 3c6c008..55c9c8e 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -159,6 +159,12 @@ static int usbg_translate_error(int error) case EEXIST: ret = USBG_ERROR_EXIST; break; + case ENODEV: + ret = USBG_ERROR_NO_DEV; + break; + case EBUSY: + ret = USBG_ERROR_BUSY; + break; default: ret = USBG_ERROR_OTHER_ERROR; } @@ -1442,34 +1448,61 @@ int usbg_get_binding_name(usbg_binding *b, char *buf, size_t len) int usbg_get_udcs(struct dirent ***udc_list) { - return scandir("/sys/class/udc", udc_list, file_select, alphasort); + 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; } -void usbg_enable_gadget(usbg_gadget *g, char *udc) +int usbg_enable_gadget(usbg_gadget *g, char *udc) { char gudc[USBG_MAX_STR_LENGTH]; struct dirent **udc_list; - int n; + int i; + int ret = USBG_ERROR_INVALID_PARAM; + + if (!g) + return ret; if (!udc) { - n = usbg_get_udcs(&udc_list); - if (!n) - return; - strcpy(gudc, udc_list[0]->d_name); - while (n--) - free(udc_list[n]); - free(udc_list); - } else - strcpy (gudc, 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 { + return ret; + } + } + + ret = usbg_write_string(g->path, g->name, "UDC", udc); - strcpy(g->udc, gudc); - usbg_write_string(g->path, g->name, "UDC", gudc); + if (ret == USBG_SUCCESS) + strcpy(g->udc, udc); + + return ret; } -void usbg_disable_gadget(usbg_gadget *g) +int usbg_disable_gadget(usbg_gadget *g) { - strcpy(g->udc, ""); - usbg_write_string(g->path, g->name, "UDC", ""); + int ret = USBG_ERROR_INVALID_PARAM; + + if (g) { + strcpy(g->udc, ""); + ret = usbg_write_string(g->path, g->name, "UDC", ""); + } + + 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