Kernel may decide to detach our gadget in some cases. A good example is when FFS daemon received a SIGSEGV and all descriptors has been closed. To avoid returning false informations to user we have to refresh UDC attribute before returning cached pointer to usbg_udc. Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- src/usbg.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/usbg.c b/src/usbg.c index b66c9b4..78490c1 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -1867,7 +1867,36 @@ int usbg_cpy_udc_name(usbg_udc *u, char *buf, size_t len) usbg_udc *usbg_get_gadget_udc(usbg_gadget *g) { - return g ? g->udc : NULL; + usbg_udc *u = NULL; + + if (!g) + goto out; + /* + * if gadget was enabled we have to check if kernel + * didn't modify the UDC file due to some errors. + * For example some FFS daemon could just get + * a segmentation fault or sth + */ + if (g->udc) { + char buf[USBG_MAX_STR_LENGTH]; + int ret; + + ret = usbg_read_string(g->path, g->name, "UDC", buf); + if (ret != USBG_SUCCESS) + goto out; + + if (!strcmp(g->udc->name, buf)) { + /* Gadget is still assigned to this UDC */ + u = g->udc; + } else { + /* Kernel decided to detach this gadget */ + g->udc->gadget = NULL; + g->udc = NULL; + } + } + +out: + return u; } int usbg_set_gadget_attrs(usbg_gadget *g, usbg_gadget_attrs *g_attrs) @@ -2450,8 +2479,12 @@ int usbg_enable_gadget(usbg_gadget *g, usbg_udc *udc) } ret = usbg_write_string(g->path, g->name, "UDC", udc->name); - if (ret == USBG_SUCCESS) { + /* If gadget has been detached and we didn't noticed + * it we have to clean up now. + */ + if (g->udc) + g->udc->gadget = NULL; g->udc = udc; udc->gadget = g; } -- 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