From 081c49e44f13a6632404755e1119113ff34710f8 Mon Sep 17 00:00:00 2001 From: Krzysztof Opasiak Date: Thu, 11 Sep 2014 20:17:22 +0200 Subject: [PATCH] libusbgx: Refresh gadget UDC while each usbg_get_gadget_udc() 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 --- src/usbg.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/usbg.c b/src/usbg.c index 0392223..7990346 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -1931,7 +1931,36 @@ out: 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) @@ -2510,8 +2539,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; } -- 2.7.4